Pass parameters to pytest fixtures
Parameterize fixtures directly, pass values indirectly from tests, and register command-line options for configurable test setup.
Use @pytest.fixture(params=[...]) when every test consuming a fixture should run for each value. Use @pytest.mark.parametrize(..., indirect=True) when the test selects the values and the fixture builds the required object.
Parameterize the fixture
import pytest
@pytest.fixture(params=['mysql', 'postgres'])
def db(request):
connection = create_connection(request.param)
yield connection
connection.close()
def test_query(db):
assert db.query('SELECT 1')
Here create_connection() is your application’s database helper, not a pytest API. Replace it with your actual setup; the example requires the relevant database services. pytest runs the test once per parameter, and the code after yield tears down each successfully created connection.
Pass values from a test with indirect parameterization
import pytest
@pytest.fixture
def user(request):
return {'role': request.param}
@pytest.mark.parametrize('user', ['admin', 'guest'], indirect=True)
def test_role(user):
assert user['role'] in {'admin', 'guest'}
indirect=True routes each value through the fixture instead of handing the raw string directly to the test. When parameterizing several arguments, indirect=['user'] selects just the fixture-backed argument.
Read a registered command-line option
Put this in conftest.py:
import pytest
def pytest_addoption(parser):
parser.addoption('--env-url', default='http://localhost:8000')
@pytest.fixture
def base_url(request):
return request.config.getoption('--env-url')
Then run pytest --env-url=https://test.example.com. Registering the option is essential; reading an undefined custom option is not enough.
FAQ
Can fixture parameters be objects?
Yes. Supply Python objects and use ids for readable test names. Parameter objects are passed as-is, so mutation can affect later uses; construct fresh state in the fixture where necessary.
Can fixtures depend on other fixtures or test parameters?
Yes. A fixture can request another fixture by argument name. It can also request a directly parameterized argument by name when that parameter is available to the consuming test. Use indirect parameterization when the parameter should drive the fixture’s own setup through request.param. Do not call a fixture function directly as an ordinary helper; use a factory fixture when a test needs to construct several objects with different arguments.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan