Explain Codes LogoExplain Codes Logo

How to pass a parameter to a fixture function in Pytest?

python
pytest
parameterized-fixtures
test-execution
Anton ShumikhinbyAnton Shumikhin·Feb 19, 2025
TLDR

Using pytest, you can create dynamic fixture factories to pass parameters. Strategically, you can define the fixture function in a way that it accepts request.param as an input. With @pytest.mark.parametrize, using indirect=True you can then inject these parameters:

import pytest @pytest.fixture def parameterized_fixture(request): # I like my parameters like I like my coffee: passed correctly and no exceptions return setup_with(request.param) @pytest.mark.parametrize('parameterized_fixture', ['value'], indirect=True) def test_example(parameterized_fixture): # If this fails, then it's just asserting its individuality assert process(parameterized_fixture) == expected_outcome

The string 'value' is communicated as a parameter to the parameterized_fixture, which test_example then uses. For more complex configurations, consider using a fixture factory:

@pytest.fixture def configurable_fixture(request): # Think of request.param as the Matrix's red pill. You never know what you're gonna get. config = {'param': request.param} return create_object_with_config(config) values_for_test = [('setting1',), ('setting2',), ('setting3',)] @pytest.mark.parametrize('configurable_fixture', values_for_test, indirect=True) def test_configurable(configurable_fixture): # Checking validity. Just like my gym membership. assert configurable_fixture.is_valid()

Advanced uses of parameterized fixtures

Tailoring test execution with optional arguments

With optional arguments in fixtures, we can tailor the execution of tests, making it more efficient. Here's how:

@pytest.fixture def smart_fixture(request): # Here, request.param is like my gym trainer, optional but highly beneficial param = getattr(request, 'param', 'default') return complex_setup(param)

Reference storage and updates

While dealing with complex test scenarios, create a class within your fixture for more organized management. This allows you to store the request and update attributes on a later stage:

class RadioStation: def __init__(self, frequency): # Initialising my radio station, don't touch that dial! self.frequency = frequency # Your favorite songs here... @pytest.fixture def radio_station(request): return RadioStation(request.param) @pytest.mark.parametrize('radio_station', ['96.7'], indirect=True) def test_station_listener(radio_station): # No frequencies were harmed in the making of this test assert radio_station.frequency == '96.7' # Frequency update, easy-peasy

Use closures to tailor fixtures

Closures within fixtures act as named parameters and provide direct control over object instantiation. They provide more elegant test setups:

def my_fixture_setup(parameter): def fixture(): return setup_object_with(parameter) return fixture @pytest.fixture def closure_fixture(request): return my_fixture_setup(request.param)() @pytest.mark.parametrize('closure_fixture', ['parameters'], indirect=True) def test_closure(closure_fixture): # PyTests are red, closures are neat, please don't fail, that would be sweet! assert closure_fixture.has_setup_correctly()

Highly tailored configurations

When your fixtures require detailed setups, consider using fixture functions that create finely tuned tests:

@pytest.fixture def dynamic_fixture(request): def configure_test(env): return test_runtime_setup(env, request.param) return configure_test @pytest.mark.parametrize('dynamic_fixture', ['production'], indirect=True) def test_dynamic_environment(dynamic_fixture): test_env = dynamic_fixture('QA') # The test_env walked into a setup, it asked: "Are you ready for me?" assert test_env.is_ready_for_tests()

Even more advantages with advanced parameterization

Streamline test setup

Even fixtures want to look their best. Spruce them up with decorators like @fixture and @parametrize for a more intuitive and faster test setup.

Consistent test logging

Everyone wants to feel special, even DLL variables. Pass them as a list using parametrization and make them a star of your test suite.

Broad customization options

Roses are red, violets are blue, our tests are flexible, thanks to indirect parametrization too!