diff --git a/CHANGES.rst b/CHANGES.rst index 8a8b4a6..d0ef19b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -11,6 +11,9 @@ Bug fixes (`#234 `_) and (`#241 `_) +- Fix tests reported as failures when rerun happened due to exception raised from fixture teardown when using only_rerun. + (`#261 `_) + Breaking changes ++++++++++++++++ @@ -23,7 +26,6 @@ Features - Add support for pytest 8.0. - 13.0 (2023-11-22) ----------------- diff --git a/src/pytest_rerunfailures.py b/src/pytest_rerunfailures.py index 75afc48..148abf0 100644 --- a/src/pytest_rerunfailures.py +++ b/src/pytest_rerunfailures.py @@ -548,9 +548,29 @@ def pytest_runtest_protocol(item, nextitem): item.ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location) reports = runtestprotocol(item, nextitem=nextitem, log=False) - for report in reports: # 3 reports: setup, call, teardown + # Check all reports to see if any rerun is needed + # (So teardown report is checked before processing call (test)) + except_found = False + for report in reports: + rerun_except_errors = _get_rerun_filter_regex(item, "rerun_except") + except_found = rerun_except_errors and _matches_any_rerun_except_error( + rerun_except_errors, report + ) + if except_found: + # One of the reports has rerun_except error match, + # no need to scan the other reports + break + + should_not_rerun = True + for report in reports: report.rerun = item.execution_count - 1 - if _should_not_rerun(item, report, reruns): + should_not_rerun = _should_not_rerun(item, report, reruns) or except_found + if not should_not_rerun: + # One of the reports should rerun, no need to scan the other reports + break + + for report in reports: # 3 reports: setup, call, teardown + if should_not_rerun: # last run or no failure detected, log normally item.ihook.pytest_runtest_logreport(report=report) else: diff --git a/tests/test_pytest_rerunfailures.py b/tests/test_pytest_rerunfailures.py index 4e721ad..f1a9fd9 100644 --- a/tests/test_pytest_rerunfailures.py +++ b/tests/test_pytest_rerunfailures.py @@ -472,7 +472,7 @@ def pytest_runtest_teardown(item): assert item.execution_count == 3""" ) result = testdir.runpytest("--reruns", "2") - assert_outcomes(result, passed=3, rerun=2) + assert_outcomes(result, passed=1, rerun=2) def test_rerun_report(testdir):