1#
2# test correct setup/teardowns at
3# module, class, and instance level
4
5def test_module_and_function_setup(testdir):
6    reprec = testdir.inline_runsource("""
7        modlevel = []
8        def setup_module(module):
9            assert not modlevel
10            module.modlevel.append(42)
11
12        def teardown_module(module):
13            modlevel.pop()
14
15        def setup_function(function):
16            function.answer = 17
17
18        def teardown_function(function):
19            del function.answer
20
21        def test_modlevel():
22            assert modlevel[0] == 42
23            assert test_modlevel.answer == 17
24
25        class TestFromClass:
26            def test_module(self):
27                assert modlevel[0] == 42
28                assert not hasattr(test_modlevel, 'answer')
29    """)
30    rep = reprec.matchreport("test_modlevel")
31    assert rep.passed
32    rep = reprec.matchreport("test_module")
33    assert rep.passed
34
35def test_module_setup_failure_no_teardown(testdir):
36    reprec = testdir.inline_runsource("""
37        l = []
38        def setup_module(module):
39            l.append(1)
40            0/0
41
42        def test_nothing():
43            pass
44
45        def teardown_module(module):
46            l.append(2)
47    """)
48    reprec.assertoutcome(failed=1)
49    calls = reprec.getcalls("pytest_runtest_setup")
50    assert calls[0].item.module.l == [1]
51
52def test_setup_function_failure_no_teardown(testdir):
53    reprec = testdir.inline_runsource("""
54        modlevel = []
55        def setup_function(function):
56            modlevel.append(1)
57            0/0
58
59        def teardown_function(module):
60            modlevel.append(2)
61
62        def test_func():
63            pass
64    """)
65    calls = reprec.getcalls("pytest_runtest_setup")
66    assert calls[0].item.module.modlevel == [1]
67
68def test_class_setup(testdir):
69    reprec = testdir.inline_runsource("""
70        class TestSimpleClassSetup:
71            clslevel = []
72            def setup_class(cls):
73                cls.clslevel.append(23)
74
75            def teardown_class(cls):
76                cls.clslevel.pop()
77
78            def test_classlevel(self):
79                assert self.clslevel[0] == 23
80
81        class TestInheritedClassSetupStillWorks(TestSimpleClassSetup):
82            def test_classlevel_anothertime(self):
83                assert self.clslevel == [23]
84
85        def test_cleanup():
86            assert not TestSimpleClassSetup.clslevel
87            assert not TestInheritedClassSetupStillWorks.clslevel
88    """)
89    reprec.assertoutcome(passed=1+2+1)
90
91def test_class_setup_failure_no_teardown(testdir):
92    reprec = testdir.inline_runsource("""
93        class TestSimpleClassSetup:
94            clslevel = []
95            def setup_class(cls):
96                0/0
97
98            def teardown_class(cls):
99                cls.clslevel.append(1)
100
101            def test_classlevel(self):
102                pass
103
104        def test_cleanup():
105            assert not TestSimpleClassSetup.clslevel
106    """)
107    reprec.assertoutcome(failed=1, passed=1)
108
109def test_method_setup(testdir):
110    reprec = testdir.inline_runsource("""
111        class TestSetupMethod:
112            def setup_method(self, meth):
113                self.methsetup = meth
114            def teardown_method(self, meth):
115                del self.methsetup
116
117            def test_some(self):
118                assert self.methsetup == self.test_some
119
120            def test_other(self):
121                assert self.methsetup == self.test_other
122    """)
123    reprec.assertoutcome(passed=2)
124
125def test_method_setup_failure_no_teardown(testdir):
126    reprec = testdir.inline_runsource("""
127        class TestMethodSetup:
128            clslevel = []
129            def setup_method(self, method):
130                self.clslevel.append(1)
131                0/0
132
133            def teardown_method(self, method):
134                self.clslevel.append(2)
135
136            def test_method(self):
137                pass
138
139        def test_cleanup():
140            assert TestMethodSetup.clslevel == [1]
141    """)
142    reprec.assertoutcome(failed=1, passed=1)
143
144def test_method_generator_setup(testdir):
145    reprec = testdir.inline_runsource("""
146        class TestSetupTeardownOnInstance:
147            def setup_class(cls):
148                cls.classsetup = True
149
150            def setup_method(self, method):
151                self.methsetup = method
152
153            def test_generate(self):
154                assert self.classsetup
155                assert self.methsetup == self.test_generate
156                yield self.generated, 5
157                yield self.generated, 2
158
159            def generated(self, value):
160                assert self.classsetup
161                assert self.methsetup == self.test_generate
162                assert value == 5
163    """)
164    reprec.assertoutcome(passed=1, failed=1)
165
166def test_func_generator_setup(testdir):
167    reprec = testdir.inline_runsource("""
168        import sys
169
170        def setup_module(mod):
171            print ("setup_module")
172            mod.x = []
173
174        def setup_function(fun):
175            print ("setup_function")
176            x.append(1)
177
178        def teardown_function(fun):
179            print ("teardown_function")
180            x.pop()
181
182        def test_one():
183            assert x == [1]
184            def check():
185                print ("check")
186                sys.stderr.write("e\\n")
187                assert x == [1]
188            yield check
189            assert x == [1]
190    """)
191    rep = reprec.matchreport("test_one", names="pytest_runtest_logreport")
192    assert rep.passed
193
194def test_method_setup_uses_fresh_instances(testdir):
195    reprec = testdir.inline_runsource("""
196        class TestSelfState1:
197            memory = []
198            def test_hello(self):
199                self.memory.append(self)
200
201            def test_afterhello(self):
202                assert self != self.memory[0]
203    """)
204    reprec.assertoutcome(passed=2, failed=0)
205
206def test_setup_that_skips_calledagain(testdir):
207    p = testdir.makepyfile("""
208        import pytest
209        def setup_module(mod):
210            pytest.skip("x")
211        def test_function1():
212            pass
213        def test_function2():
214            pass
215    """)
216    reprec = testdir.inline_run(p)
217    reprec.assertoutcome(skipped=2)
218
219def test_setup_fails_again_on_all_tests(testdir):
220    p = testdir.makepyfile("""
221        import pytest
222        def setup_module(mod):
223            raise ValueError(42)
224        def test_function1():
225            pass
226        def test_function2():
227            pass
228    """)
229    reprec = testdir.inline_run(p)
230    reprec.assertoutcome(failed=2)
231
232def test_setup_funcarg_setup_when_outer_scope_fails(testdir):
233    p = testdir.makepyfile("""
234        import pytest
235        def setup_module(mod):
236            raise ValueError(42)
237        def pytest_funcarg__hello(request):
238            raise ValueError("xyz43")
239        def test_function1(hello):
240            pass
241        def test_function2(hello):
242            pass
243    """)
244    result = testdir.runpytest(p)
245    result.stdout.fnmatch_lines([
246        "*function1*",
247        "*ValueError*42*",
248        "*function2*",
249        "*ValueError*42*",
250        "*2 error*"
251    ])
252    assert "xyz43" not in result.stdout.str()
253