Skip to content

Commit fe1fcfd

Browse files
authored
Merge pull request #7490 from bluetech/fix-dynamic-runtest-xfail
skipping: fix dynamic xfail mark added in runtest not respected
2 parents 358150c + ccad10a commit fe1fcfd

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

src/_pytest/skipping.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,17 +231,14 @@ def evaluate_xfail_marks(item: Item) -> Optional[Xfail]:
231231

232232
@hookimpl(tryfirst=True)
233233
def pytest_runtest_setup(item: Item) -> None:
234-
item._store[skipped_by_mark_key] = False
235-
236234
skipped = evaluate_skip_marks(item)
235+
item._store[skipped_by_mark_key] = skipped is not None
237236
if skipped:
238-
item._store[skipped_by_mark_key] = True
239237
skip(skipped.reason)
240238

241-
if not item.config.option.runxfail:
242-
item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)
243-
if xfailed and not xfailed.run:
244-
xfail("[NOTRUN] " + xfailed.reason)
239+
item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)
240+
if xfailed and not item.config.option.runxfail and not xfailed.run:
241+
xfail("[NOTRUN] " + xfailed.reason)
245242

246243

247244
@hookimpl(hookwrapper=True)
@@ -250,12 +247,16 @@ def pytest_runtest_call(item: Item) -> Generator[None, None, None]:
250247
if xfailed is None:
251248
item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)
252249

253-
if not item.config.option.runxfail:
254-
if xfailed and not xfailed.run:
255-
xfail("[NOTRUN] " + xfailed.reason)
250+
if xfailed and not item.config.option.runxfail and not xfailed.run:
251+
xfail("[NOTRUN] " + xfailed.reason)
256252

257253
yield
258254

255+
# The test run may have added an xfail mark dynamically.
256+
xfailed = item._store.get(xfailed_key, None)
257+
if xfailed is None:
258+
item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)
259+
259260

260261
@hookimpl(hookwrapper=True)
261262
def pytest_runtest_makereport(item: Item, call: CallInfo[None]):

testing/test_skipping.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22

33
import pytest
4+
from _pytest.pytester import Testdir
45
from _pytest.runner import runtestprotocol
56
from _pytest.skipping import evaluate_skip_marks
67
from _pytest.skipping import evaluate_xfail_marks
@@ -425,6 +426,33 @@ def test_this2(arg):
425426
result = testdir.runpytest(p)
426427
result.stdout.fnmatch_lines(["*1 xfailed*"])
427428

429+
def test_dynamic_xfail_set_during_runtest_failed(self, testdir: Testdir) -> None:
430+
# Issue #7486.
431+
p = testdir.makepyfile(
432+
"""
433+
import pytest
434+
def test_this(request):
435+
request.node.add_marker(pytest.mark.xfail(reason="xfail"))
436+
assert 0
437+
"""
438+
)
439+
result = testdir.runpytest(p)
440+
result.assert_outcomes(xfailed=1)
441+
442+
def test_dynamic_xfail_set_during_runtest_passed_strict(
443+
self, testdir: Testdir
444+
) -> None:
445+
# Issue #7486.
446+
p = testdir.makepyfile(
447+
"""
448+
import pytest
449+
def test_this(request):
450+
request.node.add_marker(pytest.mark.xfail(reason="xfail", strict=True))
451+
"""
452+
)
453+
result = testdir.runpytest(p)
454+
result.assert_outcomes(failed=1)
455+
428456
@pytest.mark.parametrize(
429457
"expected, actual, matchline",
430458
[

0 commit comments

Comments
 (0)