Skip to content

Commit df0cff1

Browse files
committed
Handle xfail(strict=True) properly in --step-wise mode (#5555)
Handle xfail(strict=True) properly in --step-wise mode
1 parent 46a0888 commit df0cff1

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

changelog/5547.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
``--step-wise`` now handles ``xfail(strict=True)`` markers properly.

src/_pytest/stepwise.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def pytest_collection_modifyitems(self, session, config, items):
7373

7474
def pytest_runtest_logreport(self, report):
7575
# Skip this hook if plugin is not active or the test is xfailed.
76-
if not self.active or "xfail" in report.keywords:
76+
if not self.active:
7777
return
7878

7979
if report.failed:

testing/test_stepwise.py

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

0 commit comments

Comments
 (0)