Search code examples
pytestpytest-dependency

pytest-dependency that depends on another class


Using pytest-dependency 0.6.0.

I have two files, both are the same tests directory.

test_set_a.py

class TestSetA:
    def test_always_passes:
        pass

test_set_b.py

@pytest.mark.dependency(depends=["TestSetA"])
class TestSetB:
    def please_dont_skip_me:
        pass

I have tried setting dependency using the filename

@pytest.mark.dependency(depends=["test_set_a.py::TestSetA"])
class TestSetB:
    def please_dont_skip_me:
        pass

I have tried setting scope to class

@pytest.mark.dependency(depends=["TestSetA"], scope="class")
class TestSetB:
    def please_dont_skip_me:
        pass

I have tried setting a filename and class scope

@pytest.mark.dependency(depends=["test_set_a.py::TestSetA"], scope="class")
class TestSetB:
    def please_dont_skip_me:
        pass

The results are always the same: TestSetA always runs and passes while TestSetB always gets skipped.

collected 2 items

[2024-10-18 17:12:24] test_set_a.py::TestSetA::test_always_passes PASSED [ 100%]

[2024-10-18 17:12:25] test_set_b.py::TestSetB::please_dont_skip_me SKIPPED (please_dont_skip_me depends on TestSetA)

How can I get TestSetB tests to only run when TestSetA tests all pass please?


Solution

  • There are a couple of things you are missing here (and what mostly can be found in the documentation).

    First, you use the scope parameter incorrectly.
    The scope parameter is the scope where the referenced test is looked up. The default scope is "module", meaning a test with the referenced name is searched in the current test module.

    If you want to reference a test inside a class in the current module, you can either use the qualified name of the test (depends=["TestClass::test_name"]) in the default module scope, or, if it is inside the same class, you can use the class scope with the test name (depends=["test_name"], scope="class"). It does not mean, that a whole test class is referenced.

    Finally, if you want to reference a test in another module as in your example, you have to use session scope, and use the fully qualified name of the test (depends=["my_module.py/TestClass::test_name"], scope="session").

    Additionally, if you want to depend on a test, you have to decorate that test with the dependency marker, e.g.:

    class TestSetA:
        @pytest.mark.dependency()
        def test_always_passes:
            pass
    

    if you want to depend on this test.

    Note that it is often easier to give the test you depend on a unique name, so you can reference that name instead of the fully qualified test name:

    class TestSetA:
        @pytest.mark.dependency(name="PassingTest")
        def test_always_passes:
            pass
    

    In the case where you depend on another test class instead of a single test, this is the only way to access it as far as I know (this part is not documented, just from my own experience).

    So to summarize: for your case you need something like:

    test_set_a.py

    @pytest.mark.dependency(name="BaseTest")
    class TestSetA:
        def test_always_passes:
            pass
    

    test_set_b.py

    @pytest.mark.dependency(depends=["BaseTest"], scope="session")
    class TestSetB:
        def please_dont_skip_me:
            pass