0
0
PytestHow-ToBeginner ยท 3 min read

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.fixture to 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.