I am trying to use pytest-dependency to make fixtures happen in order, regardless of how they are named, and regardless of the order in which they appear in a test’s argument list.
The reason I need this, is to create fixtures that require initializations, that depend on other fixtures that require initializations, and they must happen in order. I have quite a few of these, and I don’t want to rely on naming or on order in the argument list.
I also don’t want to use pytest_sessionstart
, because it can’t take fixture inputs, which causes very unclean code.
The trivial example in the doc shows how to create programmed dependencies for tests:
import pytest @pytest.mark.dependency() @pytest.mark.xfail(reason="deliberate fail") def test_a(): assert False @pytest.mark.dependency() def test_b(): pass @pytest.mark.dependency(depends=["test_a"]) def test_c(): pass @pytest.mark.dependency(depends=["test_b"]) def test_d(): pass @pytest.mark.dependency(depends=["test_b", "test_c"]) def test_e(): pass
This works with output:
============================= test session starts ============================= collecting ... collected 5 items test_sanity.py::test_z XFAIL (deliberate fail) [ 20%] @pytest.mark.dependency() @pytest.mark.xfail(reason="deliberate fail") def test_z(): > assert False E assert False test_sanity.py:6: AssertionError test_sanity.py::test_x PASSED [ 40%] test_sanity.py::test_c SKIPPED (test_c depends on test_z) [ 60%] Skipped: test_c depends on test_z test_sanity.py::test_d PASSED [ 80%] test_sanity.py::test_w SKIPPED (test_w depends on test_c) [100%] Skipped: test_w depends on test_c =================== 2 passed, 2 skipped, 1 xfailed in 0.05s ===================
Now I want to do the same for fixtures.
My attempt:
conftest.py
:
import pytest pytest_plugins = ["dependency"] @pytest.mark.dependency() @pytest.fixture(autouse=True) def zzzshould_happen_first(): assert False @pytest.mark.dependency(depends=["zzzshould_happen_first"]) @pytest.fixture(autouse=True) def should_happen_last(): assert False
and test_sanity.py
:
def test_nothing(): assert True
Outputs
test_sanity.py::test_nothing ERROR [100%] test setup failed @pytest.mark.dependency(depends=["zzzshould_happen_first"]) @pytest.fixture(autouse=True) def should_happen_last(): > assert False E assert False conftest.py:15: AssertionError
I expected the error on zzzshould_happen_first
.
Is there a way to impose ordering on fixtures, such that
- Their name is ignored
- Their order in the argument list is ignored
- Other pytest features such as
autouse
can still be applied
Advertisement
Answer
You can give a fixture as a dependency directly with pytest. Something like this:
import pytest @pytest.fixture(autouse=True) def zzzshould_happen_first(): assert False @pytest.fixture(autouse=True) def should_happen_last(zzzshould_happen_first): assert False def test_nothing(): assert True
It gives what you want:
test setup failed @pytest.fixture(autouse=True) def zzzshould_happen_first(): > assert False E assert False answer.py:7: AssertionError