17

Let's say I have these test functions:

def test_function_one():
    assert # etc...

def test_function_two():
    # should only run if test_function_one passes
    assert # etc.

How can I make sure that test_function_two only runs if test_function_one passes (I'm hoping that it's possible)?

Edit: I need this because test two is using the property that test one verifies.

Te-jé Rodgers
  • 878
  • 1
  • 7
  • 20
  • 1
    Can you explain why you need this? Is the first test setting up something the second one uses? That's generally bad. – loganfsmyth May 05 '12 at 17:59
  • 1
    This is typically a sign of a brittle test, a test that depends on more things than the unit it tests, are you *sure* you need to do this? It would (probably) be better to refactor the test and/or code under test to avoid this dependency. – Lasse V. Karlsen May 05 '12 at 18:01
  • @loganfsmyth No the first test is not setting up anything, but the second test *does* use the property that the first test verifies. – Te-jé Rodgers May 05 '12 at 18:07
  • 1
    @tjd.rodgers But then doesn't it make sense that the second test would also fail if it's inputs are incorrect. Why would you not want to run it? – loganfsmyth May 05 '12 at 18:11
  • 1
    @loganfsmyth I'd thought of that, but I didn't want a situation where the second test fails for no apparent reason and pollutes the test results while the problem really is in the first test. – Te-jé Rodgers May 05 '12 at 18:19
  • I think you want a single test, which makes two assertions. If the first assertion fails, the second will not execute. – Martin Del Vecchio May 30 '12 at 14:47
  • 8
    Don't worry about the push-back on the question. I reckon it's a good question worth asking, even if the answer isn't what you may have originally expected. There's no such thing as a bad question. – Craig McQueen Aug 31 '12 at 03:20
  • 1
    answered [here](http://stackoverflow.com/a/12579625/107049) – Thomasleveil Feb 20 '17 at 23:57
  • I think this kind of dependency between tests is fine: I would rather see (after waiting a short time) in my test output a failed `test_dashboard_x_present` and 10 skipped test cases than (after waiting a long time) 11 failed `test_dashboard_x_....` and having to look over them to notice what's going on. – DaveFar Nov 05 '20 at 07:38

5 Answers5

10

You can use plugin for pytest called pytest-dependency.

The code can look like this:

import pytest

@pytest.mark.dependency()   #First test have to have mark too
def test_function_one():
    assert 0, "Deliberate fail"

@pytest.mark.dependency(depends=["test_function_one"])
def test_function_two():
    pass   #but will be skipped because first function failed
maxt026
  • 63
  • 10
Jakub Wagner
  • 428
  • 1
  • 5
  • 15
  • 1
    this indeed skips `test_function_two` for me, but it *also skips when `test_function_one` passes* – Gulzar Jan 02 '20 at 09:18
  • 1
    @Gulzar I had the same issue and realised that you need to also decorate the function that is being depended on, even if it depends on nothing. In this example, make sure you have `@pytest.mark.dependency()` on `test_function_one`. – William Laroche Feb 13 '20 at 11:47
1

I think that a solution for yout would be to mock the value that the test1 is setting.

Ideally tests should be independent, so try to mock that value so you can always run test2 whenever you want, in fact, you should also simulate (mock) dirty values so you can see how test2 behaves if it receives unexpected data.

Juan Antonio Gomez Moriano
  • 13,103
  • 10
  • 47
  • 65
  • In theory what you say is true. But in my experience by mocking the result of the first test you end up reimplementing the functionality of the first function / class instead of reusing that code. – Akzidenzgrotesk Oct 16 '18 at 08:09
1

I'm using the plugin for pytest called pytest-dependency.

Adding to the stated above - if you are using tests inside test classes - you got to add the test class name to the function test name.

For example:

import pytest


class TestFoo:

    @pytest.mark.dependency()
    def test_A(self):
        assert False

    @pytest.mark.dependency(depends=['TestFoo::test_A'])
    def test_B(self):
        assert True

So if test_A fails - test_B won't run. and if test_A passes - test_B will run.

sheldonzy
  • 5,505
  • 9
  • 48
  • 86
  • pytest is not honoring dependency, its running the dependent steps even if it fails, no impact at all. I am using pytest 7.1.1 https://stackoverflow.com/questions/71832895/pytest-dependency-not-working-tests-run-even-if-the-dependent-tests-fail – Anmol Parida Apr 22 '22 at 07:51
0

When you have class defined make sure you use classname along with the testcase name else it will not work

class Test_class():
    @pytest.mark.dependency()
    def test1(self):
        assert False

    @pytest.mark.dependency(depends=["classname::test1"])
    def test2(self):
        print("lastname")

Output: failed=1, skipped=1

Minh-Long Luu
  • 2,393
  • 1
  • 17
  • 39
-1

I think this is what you want:

def test_function():
    assert # etc...
    assert # etc...

This meets your requirement that the second "test" (assertion) runs only if the first "test" (assertion) passes.

Martin Del Vecchio
  • 3,558
  • 2
  • 27
  • 36