pytest: parameterize fixtures in a DRY way
You could try to pass the settings as a dictionary parameter to the fixture, something like this:
import pytestfrom myapp import create_app@pytest.fixturedef app(request): settings_override = { 'SQLALCHEMY_DATABASE_URI': "sqlite:///:memory:", } params = request.param if hasattr(request, 'param') else {} return create_app({**settings_override, **params})@pytest.fixturedef db(app): do_something_to_create_the_database(app) yield dbdef test_my_application_no_override_params(db, app): ...@pytest.mark.parametrize("app", [{'BAZ': True}], indirect=True)def test_my_application_1(db, app): ...@pytest.mark.parametrize("app", [{'FOO': 'BAR'}], indirect=True)def test_my_application_2(db, app): ...
The request
object gives the fixture access to the requesting test context and can be used as an argument in any fixture.
The indirect=True
argument in the pytest.mark.parametrize
decorator passes the parameter to the optional param
attribute of the request
object, so this essentially parametrizes the fixture itself.
UPDATE:
I added the helpful addition (usage of hasattr
) as proposed by @JoeJ, which makes it possible to use a test without the additional parameters.