Skip to content

Commit 99b90f4

Browse files
authored
extend the incremental marker for parametrize (#6582)
extend the incremental marker for parametrize
2 parents 8e1d59a + d848a20 commit 99b90f4

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

doc/en/example/simple.rst

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,21 +461,49 @@ an ``incremental`` marker which is to be used on classes:
461461
462462
# content of conftest.py
463463
464-
import pytest
464+
# store history of failures per test class name and per index in parametrize (if parametrize used)
465+
_test_failed_incremental: Dict[str, Dict[Tuple[int, ...], str]] = {}
465466
466467
467468
def pytest_runtest_makereport(item, call):
468469
if "incremental" in item.keywords:
470+
# incremental marker is used
469471
if call.excinfo is not None:
470-
parent = item.parent
471-
parent._previousfailed = item
472+
# the test has failed
473+
# retrieve the class name of the test
474+
cls_name = str(item.cls)
475+
# retrieve the index of the test (if parametrize is used in combination with incremental)
476+
parametrize_index = (
477+
tuple(item.callspec.indices.values())
478+
if hasattr(item, "callspec")
479+
else ()
480+
)
481+
# retrieve the name of the test function
482+
test_name = item.originalname or item.name
483+
# store in _test_failed_incremental the original name of the failed test
484+
_test_failed_incremental.setdefault(cls_name, {}).setdefault(
485+
parametrize_index, test_name
486+
)
472487
473488
474489
def pytest_runtest_setup(item):
475490
if "incremental" in item.keywords:
476-
previousfailed = getattr(item.parent, "_previousfailed", None)
477-
if previousfailed is not None:
478-
pytest.xfail("previous test failed ({})".format(previousfailed.name))
491+
# retrieve the class name of the test
492+
cls_name = str(item.cls)
493+
# check if a previous test has failed for this class
494+
if cls_name in _test_failed_incremental:
495+
# retrieve the index of the test (if parametrize is used in combination with incremental)
496+
parametrize_index = (
497+
tuple(item.callspec.indices.values())
498+
if hasattr(item, "callspec")
499+
else ()
500+
)
501+
# retrieve the name of the first test function to fail for this class name and index
502+
test_name = _test_failed_incremental[cls_name].get(parametrize_index, None)
503+
# if name found, test has failed for the combination of class name & test name
504+
if test_name is not None:
505+
pytest.xfail("previous test failed ({})".format(test_name))
506+
479507
480508
These two hook implementations work together to abort incremental-marked
481509
tests in a class. Here is a test module example:

0 commit comments

Comments
 (0)