@@ -17,3 +17,94 @@ def test_arg(arg):
17
17
result .stdout .fnmatch_lines (
18
18
["*SETUP F arg*" , "*test_arg (fixtures used: arg)" , "*TEARDOWN F arg*" ]
19
19
)
20
+
21
+
22
+ def test_show_multi_test_fixture_setup_and_teardown_correctly_simple (testdir ):
23
+ """
24
+ Verify that when a fixture lives for longer than a single test, --setup-plan
25
+ correctly displays the SETUP/TEARDOWN indicators the right number of times.
26
+
27
+ As reported in https://github.com/pytest-dev/pytest/issues/2049
28
+ --setup-plan was showing SETUP/TEARDOWN on every test, even when the fixture
29
+ should persist through multiple tests.
30
+
31
+ (Note that this bug never affected actual test execution, which used the
32
+ correct fixture lifetimes. It was purely a display bug for --setup-plan, and
33
+ did not affect the related --setup-show or --setup-only.)
34
+ """
35
+ testdir .makepyfile (
36
+ """
37
+ import pytest
38
+ @pytest.fixture(scope = 'class')
39
+ def fix():
40
+ return object()
41
+ class TestClass:
42
+ def test_one(self, fix):
43
+ assert False
44
+ def test_two(self, fix):
45
+ assert False
46
+ """
47
+ )
48
+
49
+ result = testdir .runpytest ("--setup-plan" )
50
+ assert result .ret == 0
51
+
52
+ setup_fragment = "SETUP C fix"
53
+ setup_count = 0
54
+
55
+ teardown_fragment = "TEARDOWN C fix"
56
+ teardown_count = 0
57
+
58
+ for line in result .stdout .lines :
59
+ if setup_fragment in line :
60
+ setup_count += 1
61
+ if teardown_fragment in line :
62
+ teardown_count += 1
63
+
64
+ # before the fix this tests, there would have been a setup/teardown
65
+ # message for each test, so the counts would each have been 2
66
+ assert setup_count == 1
67
+ assert teardown_count == 1
68
+
69
+
70
+ def test_show_multi_test_fixture_setup_and_teardown_same_as_setup_show (testdir ):
71
+ """
72
+ Verify that SETUP/TEARDOWN messages match what comes out of --setup-show.
73
+ """
74
+ testdir .makepyfile (
75
+ """
76
+ import pytest
77
+ @pytest.fixture(scope = 'session')
78
+ def sess():
79
+ return True
80
+ @pytest.fixture(scope = 'module')
81
+ def mod():
82
+ return True
83
+ @pytest.fixture(scope = 'class')
84
+ def cls():
85
+ return True
86
+ @pytest.fixture(scope = 'function')
87
+ def func():
88
+ return True
89
+ def test_outside(sess, mod, cls, func):
90
+ assert True
91
+ class TestCls:
92
+ def test_one(self, sess, mod, cls, func):
93
+ assert True
94
+ def test_two(self, sess, mod, cls, func):
95
+ assert True
96
+ """
97
+ )
98
+
99
+ plan_result = testdir .runpytest ("--setup-plan" )
100
+ show_result = testdir .runpytest ("--setup-show" )
101
+
102
+ # the number and text of these lines should be identical
103
+ plan_lines = [
104
+ l for l in plan_result .stdout .lines if "SETUP" in l or "TEARDOWN" in l
105
+ ]
106
+ show_lines = [
107
+ l for l in show_result .stdout .lines if "SETUP" in l or "TEARDOWN" in l
108
+ ]
109
+
110
+ assert plan_lines == show_lines
0 commit comments