I write tests using pytest. I need to do certain things before and after some tests. How can I automatically set the some_fixture
to the test function if it is marked with some_marker
?
To implement this, I wrote a context manager + fixture.
# conftest.py
class ContextManager:
def __init__(self, some_args):
self.some_args = some_args
def __enter__(self):
pass # do something
def __exit__(self, exc_type, exc_val, exc_tb):
pass # do something
@pytest.fixture
def some_fixture(request):
some_args = request.node.get_closest_marker("some_marker").kwargs.get("some_args")
with ContextManager(some_args):
yield
def pytest_configure(config):
config.addinivalue_line("markers", "some_marker(some_args): ...")
But this is inconvenient because I need to constantly specify the fixture.
# module_test.py
@pytest.mark.some_marker(some_args=[...])
def test_function(some_fixture):
pass
If you don't want to add the fixture name manually, you can do so during the item collection. You can access and change the fixture names of an item via Function.fixturenames
(that is for some reason not listed in the documentation for Function, but mentioned elsewhere, so I guess it is part of the API):
conftest.py
def pytest_collection_modifyitems(items):
for item in items:
if item.get_closest_marker("some_marker"):
item.fixturenames.append("some_fixture")
module_test.py
@pytest.mark.some_marker(some_args=[...])
def test_function():
pass
As long as you don't need to access the fixture by name in your test, this should work.