What Is the Difference Between Fixtures and Hooks?
Beginners often confuse fixtures with hooks such as beforeEach() and afterEach().
Both can help with test setup, but they serve different purposes.
| Feature | Fixtures | Hooks |
|---|---|---|
| Main purpose | Provide resources and manage their lifecycle | Run setup or cleanup steps at specific points |
| Reusability | Can be shared and composed across tests | Can be organized within test files or groups |
| Dependency handling | Supports explicit fixture dependencies | Usually relies on variables or other setup mechanisms |
| Cleanup | Managed through fixture lifecycle | Written in cleanup hooks when needed |
| Example | page, loggedInPage | beforeEach(), afterEach() |
For example, you might use beforeEach() to navigate to a common starting URL, while a custom fixture could provide an authenticated page or reusable test data.
Fixtures and hooks can also be used together when that makes the test structure clearer.
Common Mistakes to Avoid
When learning Playwright fixtures, watch out for these mistakes:
1. Forgetting to call use()
In a custom fixture, use() passes the fixture value to the test and marks the point at which the test can use it.
2. Repeating the same setup in every test
Consider creating a custom fixture when multiple tests need the same setup logic.
3. Sharing mutable data between tests
Shared state can cause unexpected failures, especially when tests run in parallel.
4. Using worker scope for everything
Worker-scoped fixtures are appropriate only when the resource can safely be shared across tests in the same worker.
5. Forgetting cleanup
If your fixture creates external resources, such as temporary accounts or records, make sure the necessary cleanup is implemented.
6. Creating fixtures for unnecessary tasks
A fixture is most useful when it improves reuse, setup, resource management, or test readability. Not every line of test code needs a custom fixture.
Best Practices for Using Playwright Fixtures
Follow these practices to keep your automation framework maintainable:
- Use built-in fixtures whenever they meet your requirements.
- Create custom fixtures for repeated setup and reusable resources.
- Keep fixture names meaningful and easy to understand.
- Choose test scope by default unless a broader scope is justified.
- Use worker scope only for resources that can safely be shared.
- Add cleanup logic for resources that your fixtures create.
- Avoid placing unrelated test assertions inside shared fixtures.
- Keep credentials and sensitive configuration out of source code.
- Run tests independently to identify accidental dependencies.
These practices can help you build a cleaner and more reliable Playwright automation framework.