A pytest plugin that enables the use of fixtures within pytest.mark.parametrize decorators through lazy evaluation
npx @tessl/cli install tessl/pypi-pytest-lazy-fixture@0.6.0A pytest plugin that enables the use of fixtures within pytest.mark.parametrize decorators through lazy evaluation. This plugin solves the limitation where fixtures cannot normally be used directly in parametrize decorators by providing a lazy evaluation mechanism that resolves fixture values at test runtime.
pip install pytest-lazy-fixtureimport pytest
# The plugin automatically makes lazy_fixture available via pytest namespace
pytest.lazy_fixture('fixture_name')Direct import:
from pytest_lazyfixture import lazy_fixture, is_lazy_fixture, LazyFixtureimport pytest
# Define a fixture with parameters
@pytest.fixture(params=[1, 2])
def one(request):
return request.param
# Use lazy_fixture in parametrize to reference the fixture
@pytest.mark.parametrize('arg1,arg2', [
('val1', pytest.lazy_fixture('one')),
('val2', pytest.lazy_fixture('one')),
])
def test_func(arg1, arg2):
assert arg2 in [1, 2]
# Multiple lazy fixtures in one parametrize
@pytest.fixture(params=[3, 4])
def two(request):
return request.param
@pytest.mark.parametrize('arg1,arg2,arg3', [
('val1', pytest.lazy_fixture('one'), pytest.lazy_fixture('two')),
])
def test_multiple(arg1, arg2, arg3):
assert arg2 in [1, 2]
assert arg3 in [3, 4]
# Use in fixture parameters (indirect parametrization)
@pytest.fixture(params=[
pytest.lazy_fixture('one'),
pytest.lazy_fixture('two')
])
def combined(request):
return request.param
def test_combined(combined):
assert combined in [1, 2, 3, 4]The pytest-lazy-fixture plugin uses pytest's hook system to intercept and modify test collection and execution. The core design enables lazy evaluation through several key components:
lazy_fixture function in pytest namespace for convenient accessThe plugin defers fixture resolution until test runtime rather than collection time:
This design allows fixtures to be used in @pytest.mark.parametrize decorators while maintaining pytest's normal fixture dependency resolution and scoping rules.
Creates lazy fixture references that are resolved at test runtime rather than collection time.
def lazy_fixture(names):
"""
Create lazy fixture references for use in parametrize decorators.
Args:
names (str or list): Single fixture name or list of fixture names
Returns:
LazyFixture or list[LazyFixture]: Lazy fixture wrapper(s)
"""Usage examples:
# Single fixture
lazy_ref = pytest.lazy_fixture('my_fixture')
# Multiple fixtures
lazy_refs = lazy_fixture(['fixture1', 'fixture2'])Utility function to check if a value is a lazy fixture instance.
def is_lazy_fixture(val):
"""
Check if a value is a LazyFixture instance.
Args:
val: Value to check
Returns:
bool: True if val is a LazyFixture instance
"""Usage example:
if is_lazy_fixture(some_value):
# Handle lazy fixture
actual_value = request.getfixturevalue(some_value.name)The core wrapper class that holds fixture names for lazy evaluation.
class LazyFixture(object):
"""
Wrapper class for lazy fixture evaluation.
Attributes:
name (str): Name of the fixture to be resolved
"""
def __init__(self, name):
"""
Initialize lazy fixture with fixture name.
Args:
name (str): Name of the fixture to wrap
"""
def __repr__(self):
"""
String representation of the lazy fixture.
Returns:
str: Formatted string showing class name and fixture name
"""
def __eq__(self, other):
"""
Compare LazyFixture instances by fixture name.
Args:
other (LazyFixture): Another LazyFixture instance
Returns:
bool: True if fixture names are equal
"""The plugin automatically integrates with pytest through entry points and hooks:
# Available after plugin installation
pytest.lazy_fixture # Function accessible via pytest namespace@pytest.mark.parametrizeThe plugin works by:
request.getfixturevalue()Key internal functions (not part of public API):
pytest_runtest_setup(): Modifies test setup to handle lazy fixturespytest_fixture_setup(): Resolves lazy fixtures used as fixture parameterspytest_generate_tests(): Normalizes test generation for lazy fixturessorted_by_dependency(): Ensures fixtures are resolved in dependency orderThe plugin handles various pytest version compatibility issues and provides appropriate error handling for: