How to Use Fixture Factory Pattern in pytest for Flexible Tests
In
pytest, the fixture factory pattern means creating a fixture that returns a function to generate test data dynamically. This lets you customize test inputs easily by calling the factory function with different parameters inside your tests.Syntax
The fixture factory pattern uses a @pytest.fixture that returns a function. This returned function acts as a factory to create test data or objects with parameters you specify.
Key parts:
@pytest.fixture: marks the factory fixture.- Factory function inside fixture: accepts parameters to customize data.
- Test uses the factory by calling it with arguments.
python
import pytest @pytest.fixture def user_factory(): def create_user(name, age): return {'name': name, 'age': age} return create_user
Example
This example shows a fixture factory user_factory that creates user dictionaries with different names and ages. The test calls the factory to get customized users and asserts their properties.
python
import pytest @pytest.fixture def user_factory(): def create_user(name, age): return {'name': name, 'age': age} return create_user def test_user_ages(user_factory): user1 = user_factory('Alice', 30) user2 = user_factory('Bob', 25) assert user1['name'] == 'Alice' assert user1['age'] == 30 assert user2['name'] == 'Bob' assert user2['age'] == 25
Output
============================= test session starts ==============================
collected 1 item
test_example.py . [100%]
============================== 1 passed in 0.03s ===============================
Common Pitfalls
Common mistakes when using fixture factories include:
- Not returning the inner factory function from the fixture, so tests get
None. - Trying to parametrize the fixture itself instead of using the factory function for dynamic data.
- Mutating shared data inside the factory, causing tests to interfere.
Always return a new object from the factory function to keep tests isolated.
python
import pytest # Wrong: fixture returns None because inner function is not returned @pytest.fixture def broken_factory(): def create(): return 42 # Missing return statement here # Right: return the inner function @pytest.fixture def fixed_factory(): def create(): return 42 return create
Quick Reference
Fixture Factory Pattern Tips:
- Use
@pytest.fixtureto define the factory fixture. - Return a function that accepts parameters to create test data.
- Call the factory function inside tests to get customized objects.
- Keep factory functions pure and avoid shared mutable state.
Key Takeaways
Use a fixture that returns a function to create flexible test data in pytest.
Call the factory function inside tests with parameters to customize data.
Always return the inner factory function from the fixture to avoid None results.
Avoid shared mutable state in factory functions to keep tests independent.
Fixture factories improve test readability and reusability by centralizing data creation.