diff --git a/CHANGES.rst b/CHANGES.rst index 59408a5..2228412 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,14 @@ Changelog 16.5 (unreleased) ----------------- -- Nothing changed yet. +Bug fixes ++++++++++ + +- Prevent a rerun when a fixture teardown raises an error matching + ``--rerun-except``. Previously only the error from the current test stage + was considered, so a ``--rerun-except``-matching error raised during + teardown was ignored and the test was rerun anyway. + Fixes `#270 `_. 16.4 (2026-07-01) diff --git a/src/pytest_rerunfailures.py b/src/pytest_rerunfailures.py index 4a3e0b1..d43dd57 100644 --- a/src/pytest_rerunfailures.py +++ b/src/pytest_rerunfailures.py @@ -500,7 +500,7 @@ def _should_hard_fail_on_error(item, report, excinfo): def _should_not_rerun(item, report, reruns): xfail = hasattr(report, "wasxfail") - is_terminal_error = item._terminal_errors[report.when] + is_terminal_error = any(item._terminal_errors.values()) condition = get_reruns_condition(item) has_failed_subtests = ( report.when == "call" and _get_num_failed_subtests(item, report) > 0 diff --git a/tests/test_pytest_rerunfailures.py b/tests/test_pytest_rerunfailures.py index e363f14..52c30a4 100644 --- a/tests/test_pytest_rerunfailures.py +++ b/tests/test_pytest_rerunfailures.py @@ -855,6 +855,26 @@ def test_will_not_run(fixture_setup_fails): assert_outcomes(result, passed=0, error=1, rerun=num_reruns) +def test_rerun_except_teardown_error_prevents_rerun(testdir): + """Teardown errors covered by --rerun-except must prevent reruns.""" + testdir.makepyfile( + """ + import pytest + + @pytest.fixture() + def broken_fixture(): + yield + raise ValueError("teardown error") + + def test_fail_in_fixture(broken_fixture): + assert False + """ + ) + + result = testdir.runpytest("--reruns", "1", "--rerun-except", "ValueError") + assert_outcomes(result, passed=0, failed=1, error=1, rerun=0) + + @pytest.mark.parametrize( "condition, expected_reruns", [