Package: pytest-param-scope
pytest-param-scopeThe pytest parametrize scope fixture workaround.pytest-param-scopeprovides aparam_scopemarker to pass setup and teardown functions to a parametrized function.There's also aparam_scopefixture to allow the return value of the setup function to be passed to the test.InstallationFrom PyPI:$ pip install pytest-param-scopeExampleimportpytestdefparam_setup():print('\nparam setup')return'some data from setup'defparam_teardown():print('\nparam teardown')@pytest.mark.param_scope(param_setup,param_teardown)@pytest.mark.parametrize('x',['a','b','c'])deftest_param(x,param_scope):"""mark.param_scope is used to passsetup and teardown functions to fixtureparam_scope fixture is necessary if youwant to use the value from setup"""assertparam_scope=='some data from setup'Let's see it run:(venv)$pytest-s-vtest_param_scope.py::test_param==================testsessionstarts===================collected3itemstest_param_scope.py::test_param[a]paramsetup
PASSED
test_param_scope.py::test_param[b]PASSED
test_param_scope.py::test_param[c]PASSED
paramteardown===================3passedin0.01s====================What are we seeing?Setup is run before the first parameter in a set.Teardown is run after the last parameter.Theparam_scopefixture holds the return value of the setup function.Similarities to FixturesTeardown is not run if the setup fails.Setup is run once, even though the value can be retrieved by all parametrized test cases.If an exception occurs in setup, the test will report Error and not run. The teardown will also not run.If an exception occurs in teardown, the LAST parametrized test case to run results in BOTH PASS and Error. This is weird, but consistent with pytest fixtures.You can combine setup and teardown in one functionYou can provide a function separated by ayieldto put both setup and teardown in one function.However, there's a trick to doing this:Either, passNoneas the teardown.Or usewith_args, as in@pytest.mark.param_scope.with_args(my_func)Here's a combo setup/teardown function:defsetup_and_teardown():print('\nsetup')yield42print('\nteardown')Calling it withNonefor teardown:importpytest@pytest.mark.param_scope(setup_and_teardown,None)@pytest.mark.parametrize('x',['a','b','c'])deftest_yield(x,param_scope):assertparam_scope==42Or usingwith_args:@pytest.mark.param_scope.with_args(setup_and_teardown)@pytest.mark.parametrize('x',['a','b','c'])deftest_just_one_func(x,param_scope):assertparam_scope==42Both of these examples are inexamples/test_yield.py.More examplesPlease seeexamplesdirectory in the repo.LimitationsThe implementation is a total hack and relies on global variables and looking up the next test to see when to run the teardown. There is undoubtedly room for improvement.Withpytest-xdist: I haven't come up with a failing case yet, but it seems like this will be sketchy with tests running in parallel.Withpytest-repeat: This actually works great withpytest-repeat, as repeat works by generating parametrized tests.FAQWhy not just use existing fixture scopes?There isn't a scope that quite fits.Function: runs setup before and after each parametrized test case.Class: Kinda works if you put only one function in a test class.Module: Too wide.Session: Way too wide.I want a setup that runs before all parametrized test cases, and clean up after the last one.Why implement this as a plugin and not add this functionality to pytest core?A couple reasons.I'm not sure we want this funcitonality in core pytest. Playing with it as a plugin will tell us if it's important to people.Implementing it as a plugin is faster to get it out there and usable.ContributingContributions are very welcome. Tests can be run withtox.LicenseDistributed under the terms of theMITlicense, "pytest-param-scope" is free and open source softwareIssuesIf you encounter any problems, pleasefile an issuealong with a detailed description.ChangelogSeechangelog.md