Factory fixtures help create test data easily and consistently. They make tests simpler and cleaner by reusing setup code.
Factory fixtures in PyTest
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
PyTest
import pytest @pytest.fixture def factory_name(): def _factory(**kwargs): # create and return test object using kwargs return SomeObject(**kwargs) return _factory
The fixture returns a function that creates objects when called.
You can pass different parameters to customize each test object.
Examples
PyTest
import pytest @pytest.fixture def user_factory(): def _factory(name="John", age=30): return {"name": name, "age": age} return _factory
PyTest
def test_user_age(user_factory): user = user_factory(age=25) assert user["age"] == 25
Sample Program
This test file defines a factory fixture to create product dictionaries. Two tests check default and custom product data.
PyTest
import pytest @pytest.fixture def product_factory(): def _factory(name="Book", price=10.0): return {"name": name, "price": price} return _factory def test_default_product(product_factory): product = product_factory() assert product["name"] == "Book" assert product["price"] == 10.0 def test_custom_product(product_factory): product = product_factory(name="Pen", price=2.5) assert product["name"] == "Pen" assert product["price"] == 2.5
Important Notes
Factory fixtures improve test readability and reduce duplication.
Use keyword arguments to customize objects easily.
Keep factory fixtures simple and focused on creating test data.
Summary
Factory fixtures return a function to create test objects.
They help reuse and customize test data setup.
Using them keeps tests clean and easy to maintain.
Practice
1. What is the main purpose of a factory fixture in pytest?
easy
Solution
Step 1: Understand what factory fixtures do
Factory fixtures return a function that can create test data with different parameters as needed.Step 2: Compare with other options
Running tests in parallel, generating reports, or mocking APIs are different pytest features, not factory fixtures.Final Answer:
To create reusable test data with flexible parameters -> Option BQuick Check:
Factory fixture = reusable flexible test data creator [OK]
Hint: Factory fixtures build test data functions fast [OK]
Common Mistakes:
- Confusing factory fixtures with mocking
- Thinking factory fixtures run tests
- Assuming factory fixtures generate reports
2. Which of the following is the correct way to define a simple factory fixture in pytest?
easy
Solution
Step 1: Identify factory fixture structure
A factory fixture returns a function that accepts parameters to create test data dynamically.Step 2: Check each option
@pytest.fixture def user_factory(): def create_user(name): return {'name': name} return create_user defines a fixture returning a function that takes a name and returns a dict, which is correct. Options A, C, and D do not return a function, so they are not factory fixtures.Final Answer:
@pytest.fixture def user_factory(): def create_user(name): return {'name': name} return create_user -> Option CQuick Check:
Factory fixture = fixture returning a function [OK]
Hint: Factory fixtures return a function inside the fixture [OK]
Common Mistakes:
- Returning data directly instead of a function
- Missing @pytest.fixture decorator
- Defining fixture with parameters directly
3. Given the following pytest code, what will be the output of the test?
@pytest.fixture
def number_factory():
def create_number(x):
return x * 2
return create_number
def test_double(number_factory):
result = number_factory(5)
assert result == 10
print(result)medium
Solution
Step 1: Understand the factory fixture behavior
The fixture returns a function that doubles the input number.Step 2: Analyze the test function
The test calls number_factory(5), which returns 5 * 2 = 10, then asserts result == 10, which is true, so test passes and prints 10.Final Answer:
Test passes and prints 10 -> Option AQuick Check:
5 * 2 = 10, assertion true [OK]
Hint: Factory fixture returns function; call it with argument [OK]
Common Mistakes:
- Thinking fixture itself is called with argument
- Expecting print output to fail test
- Confusing assertion logic
4. Identify the error in this factory fixture code and how to fix it:
@pytest.fixture
def item_factory():
def create_item(name, price):
return {'name': name, 'price': price}
return create_item
def test_item(item_factory):
item = item_factory('Book')
assert item['price'] == 10medium
Solution
Step 1: Check the factory function parameters
The factory function create_item expects two arguments: name and price.Step 2: Analyze the test call
The test calls item_factory('Book') with only one argument, missing price, causing an error or wrong data.Final Answer:
The factory function is missing the 'price' argument; fix by passing price when calling. -> Option DQuick Check:
Factory args must match call args [OK]
Hint: Match factory function parameters with call arguments [OK]
Common Mistakes:
- Calling factory with fewer arguments than defined
- Returning dict directly instead of function
- Misusing fixture as a simple variable
5. You want to create a factory fixture that builds user dictionaries with optional age and default country='USA'. Which of the following implementations correctly achieves this?
hard
Solution
Step 1: Understand factory fixture with optional/default parameters
The factory fixture should return a function that accepts parameters with defaults for optional values.Step 2: Evaluate each option
@pytest.fixture def user_factory(): def create_user(name, age=None, country='USA'): return {'name': name, 'age': age, 'country': country} return create_user correctly defines a fixture returning a function with default age=None and country='USA'. @pytest.fixture def user_factory(name, age=None, country='USA'): return {'name': name, 'age': age, 'country': country} is not a factory fixture because it takes parameters directly. @pytest.fixture def user_factory(): return {'name': 'default', 'age': None, 'country': 'USA'} returns a fixed dict, not a factory. @pytest.fixture def user_factory(): def create_user(name, age, country): return {'name': name, 'age': age, 'country': country} return create_user requires all parameters without defaults, so age and country are not optional.Final Answer:
@pytest.fixture def user_factory(): def create_user(name, age=None, country='USA'): return {'name': name, 'age': age, 'country': country} return create_user -> Option AQuick Check:
Factory fixture returns function with defaults [OK]
Hint: Factory fixture returns function with default parameters [OK]
Common Mistakes:
- Defining fixture with parameters directly
- Not providing default values for optional args
- Returning fixed data instead of a function
