Skip to content

Commit 8651d88

Browse files
committed
Handle xfail(strict=True) properly in --step-wise mode
Fix #5547
1 parent 95824c5 commit 8651d88

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
@@ -72,7 +72,7 @@ def pytest_collection_modifyitems(self, session, config, items):
7272

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

7878
if report.failed:

testing/test_stepwise.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,56 @@ def test_stop_on_collection_errors(broken_testdir, broken_first):
165165
files.reverse()
166166
result = broken_testdir.runpytest("-v", "--strict-markers", "--stepwise", *files)
167167
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

Comments
 (0)