Package: pytest-paramark
Configure pytest fixtures using combination of parametrize and markersWhat is this thing?The problemPytest fixture names must be unique within the whole dependency graph
(#3966).This means that when you want to parametrize fixtures, each parameter name must
be unique:importpytest@pytest.fixturedeffoo(foo_option):return{'option':foo_option}@pytest.fixturedefbar(bar_option):return{'option':bar_option}@pytest.mark.parametrize('foo_option, bar_option',[(42,24),])deftest_options(foo,bar):assertfoo['option']==42assertbar['option']==24Also, if you want to provide default vaules for options, they need to be fixtures as well:@pytest.fixturedeffoo_option():return'default_foo_option'@pytest.fixturedefbar_option():return'default_bar_option'@pytest.fixturedeffoo(foo_option):return{'option':foo_option}@pytest.fixturedefbar(bar_option):return{'option':bar_option}deftest_options(foo,bar):assertfoo['option']=='default_foo_option'assertbar['option']=='default_bar_option'This is inconvenient when number of options and fixtures increases, and you end
up with lots of boilerplate code like this:@pytest.fixture()defapp_elements():{}@pytest.fixture()defapp_sequence():returnNone@pytest.fixture()defapp_uuid(uuid=None):returnuuidoruuid4()@pytest.fixturedefapp_app_key():returnApplicationKey(bytes.fromhex('63964771734fbd76e3b40519d1d94a48'))@pytest.fixturedefapp_net_key():returnNetworkKey(bytes.fromhex('7dd7364cd842ad18c17c2b820c84c3d6'))@pytest.fixturedefapp_dev_key():returnDeviceKey(bytes.fromhex('9d6dd0e96eb25dc19a40ed9914f8f03f'))@pytest.fixturedefapp_addr():return0x5f2@pytest.fixturedefapp_iv_index():return0@pytest.fixture()defapplication(app_uuid,app_elements,app_dev_key,app_app_key,app_net_ket,app_addr,app_iv_index,app_sequence):...The solutionThis plugin provides a cleaner way to pass such options to selected fixutres,
by implementing a magic fixture calledparamark, which returns adifferentvalue
for each of the fixtures that depend on it:@pytest.fixturedeffoo(paramark):returnparamark@pytest.fixturedefbar(paramark):returnparamark@pytest.mark.foo(option=42)@pytest.mark.bar(option=24)deftest_options(foo,bar):assertfoo['option']==42assertbar['option']==24As can be seen in the example,paramarkreturns a dictionary with keys and
values pulled from a custom mark withthe same nameas the dependant fixture.
Note that these marks still need to beregistered.This also works withparametrize, by extending the argument name syntax to include a dot:@pytest.mark.parametrize('foo.option, bar.option',[(43,24),])@pytest.mark.bar(option=24)deftest_options(foo,bar):assertfoo['option']==42assertbar['option']==24or, if you want to parametrize the whole dictionary:@pytest.mark.parametrize('foo.*, bar.option',[({'option':42,'another: 17}, 24),])@pytest.mark.bar(option=24)deftest_options(foo,bar):assertfoo['option']==42assertfoo['another']==17assertbar['option']==24Having this, defining default values no longer requires separate fixture for each option:@pytest.fixturedeffoo(paramark):default={'option':'default_foo_option'}return{**default,**paramark)@pytest.fixturedefbar(paramark):default={'option':'default_bar_option'}return{**default,**paramark)@pytest.mark.foo(option='custom_foo_option')deftest_options(foo,bar):assertfoo['option']=='custom_foo_option'assertbar['option']=='default_bar_option'or, if you want to be safer and fancier:importtyping@pytest.fixturedeffoo(paramark):classFoo(typing.NamedTuple):option:str='default_foo_option'returnFoo(**paramark)deftest_options(foo):assertfoo.option=='default_foo_option'InstallationYou can install “pytest-paramark” viapipfromPyPI:$ pip install pytest-paramarkContributingContributions are very welcome. Tests can be run withtox, please ensure
the coverage at least stays the same before you submit a pull request.LicenseDistributed under the terms of theMITlicense, “pytest-paramark” is free and open source softwareIssuesIf you encounter any problems, pleasefile an issuealong with a detailed description.