Let's say I have a pytest fixture established in my conftest.py file that looks like:
def live_fixture():
# network access here...
pass
I use this same fixture in many test functions, say that test_spam.py has some test functions:
@pytest.mark.live
def test_one(live_fixture):
assert 1
def test_one():
assert 2
@pytest.mark.live
def test_three(live_fixture):
assert 3
I use the @pytest.mark.live
decoration on the first and third test functions because those two tests both depend on the fixture live_fixture
, which goes out over the network and does stuff. Rationale: I like having a reliable subset of my tests pass offline, such that e.g.
py.test -m "not live" test_spam.py --blockage
will reliably pass (using the nifty pytest-blockage module to enforce the no-network-access restriction).
But writing out the @pytest.mark.live
decoration on each test function which uses the live_fixture
here is tedious and error-prone. Is there some way to have that fixture declare that any test function which uses it should automatically have @pytest.mark.live
decoration applied to it, or some way to detect inside file test_spam.py that test_one
and test_three
use that live_fixture
and thus should be effectively decorated @pytest.mark.live
?
I found another plausible solution, by trying to dig out how pytest.mark works.
I found class Node has a method "add_marker", which should be the exact method which implement feature pytest.mark. And class Item is extended from Node.
So my solution is:
Example: Add following method in conftest.py
def pytest_itemcollected(item):
""" we just collected a test item. """
if 'live_fixture' in item.fixturenames:
item.add_marker('live')
I hope at least my answer would inspire somebody to think of a more decent way.