@@ -165,3 +165,56 @@ def test_stop_on_collection_errors(broken_testdir, broken_first):
165
165
files .reverse ()
166
166
result = broken_testdir .runpytest ("-v" , "--strict-markers" , "--stepwise" , * files )
167
167
result .stdout .fnmatch_lines ("*errors during collection*" )
168
+
169
+
170
+ def test_xfail_handling (testdir ):
171
+ """Ensure normal xfail is ignored, and strict xfail interrupts the session in sw mode
172
+
173
+ (#5547)
174
+ """
175
+ contents = """
176
+ import pytest
177
+ def test_a(): pass
178
+
179
+ @pytest.mark.xfail(strict={strict})
180
+ def test_b(): assert {assert_value}
181
+
182
+ def test_c(): pass
183
+ def test_d(): pass
184
+ """
185
+ testdir .makepyfile (contents .format (assert_value = "0" , strict = "False" ))
186
+ result = testdir .runpytest ("--sw" , "-v" )
187
+ result .stdout .fnmatch_lines (
188
+ [
189
+ "*::test_a PASSED *" ,
190
+ "*::test_b XFAIL *" ,
191
+ "*::test_c PASSED *" ,
192
+ "*::test_d PASSED *" ,
193
+ "* 3 passed, 1 xfailed in *" ,
194
+ ]
195
+ )
196
+
197
+ testdir .makepyfile (contents .format (assert_value = "1" , strict = "True" ))
198
+ result = testdir .runpytest ("--sw" , "-v" )
199
+ result .stdout .fnmatch_lines (
200
+ [
201
+ "*::test_a PASSED *" ,
202
+ "*::test_b FAILED *" ,
203
+ "* Interrupted*" ,
204
+ "* 1 failed, 1 passed in *" ,
205
+ ]
206
+ )
207
+
208
+ # because we are writing to the same file, mtime might not be affected enough to
209
+ # invalidate the cache, making this next run flaky
210
+ testdir .tmpdir .join ("__pycache__" ).remove ()
211
+ testdir .makepyfile (contents .format (assert_value = "0" , strict = "True" ))
212
+ result = testdir .runpytest ("--sw" , "-v" )
213
+ result .stdout .fnmatch_lines (
214
+ [
215
+ "*::test_b XFAIL *" ,
216
+ "*::test_c PASSED *" ,
217
+ "*::test_d PASSED *" ,
218
+ "* 2 passed, 1 deselected, 1 xfailed in *" ,
219
+ ]
220
+ )
0 commit comments