diff --git a/pytest_rerunfailures.py b/pytest_rerunfailures.py index df42b38..c21ceeb 100644 --- a/pytest_rerunfailures.py +++ b/pytest_rerunfailures.py @@ -20,7 +20,6 @@ else: import importlib_metadata - try: from xdist.newhooks import pytest_handlecrashitem @@ -29,7 +28,6 @@ except ImportError: HAS_PYTEST_HANDLECRASHITEM = False - PYTEST_GTE_63 = parse_version(pytest.__version__) >= parse_version("6.3.0") @@ -66,8 +64,8 @@ def pytest_addoption(parser): type=str, default=None, help="If passed, only rerun errors matching the regex provided. " - "Pass this flag multiple times to accumulate a list of regexes " - "to match", + "Pass this flag multiple times to accumulate a list of regexes " + "to match", ) group._addoption( "--reruns", @@ -90,8 +88,8 @@ def pytest_addoption(parser): type=str, default=None, help="If passed, only rerun errors other than matching the " - "regex provided. Pass this flag multiple times to accumulate a list " - "of regexes to match", + "regex provided. Pass this flag multiple times to accumulate a list " + "of regexes to match", ) arg_type = "string" parser.addini("reruns", RERUNS_DESC, type=arg_type) @@ -266,6 +264,14 @@ def _get_rerun_filter_regex(item, regex_name): def _matches_any_rerun_error(rerun_errors, report): + return _try_match_reprcrash(rerun_errors, report) + + +def _matches_any_rerun_except_error(rerun_except_errors, report): + return _try_match_reprcrash(rerun_except_errors, report) + + +def _try_match_reprcrash(rerun_errors, report): for rerun_regex in rerun_errors: try: if re.search(rerun_regex, report.longrepr.reprcrash.message): @@ -276,13 +282,6 @@ def _matches_any_rerun_error(rerun_errors, report): return False -def _matches_any_rerun_except_error(rerun_except_errors, report): - for rerun_regex in rerun_except_errors: - if re.search(rerun_regex, report.longrepr.reprcrash.message): - return True - return False - - def _should_hard_fail_on_error(item, report): if report.outcome != "failed": return False @@ -316,11 +315,11 @@ def _should_not_rerun(item, report, reruns): is_terminal_error = _should_hard_fail_on_error(item, report) condition = get_reruns_condition(item) return ( - item.execution_count > reruns - or not report.failed - or xfail - or is_terminal_error - or not condition + item.execution_count > reruns + or not report.failed + or xfail + or is_terminal_error + or not condition ) diff --git a/test_pytest_rerunfailures.py b/test_pytest_rerunfailures.py index 7e203aa..b0b11f2 100644 --- a/test_pytest_rerunfailures.py +++ b/test_pytest_rerunfailures.py @@ -6,7 +6,6 @@ from pytest_rerunfailures import HAS_PYTEST_HANDLECRASHITEM - pytest_plugins = "pytester" has_xdist = HAS_PYTEST_HANDLECRASHITEM @@ -42,14 +41,14 @@ def check_outcome_field(outcomes, field_name, expected_value): def assert_outcomes( - result, - passed=1, - skipped=0, - failed=0, - error=0, - xfailed=0, - xpassed=0, - rerun=0, + result, + passed=1, + skipped=0, + failed=0, + error=0, + xfailed=0, + xpassed=0, + rerun=0, ): outcomes = result.parseoutcomes() check_outcome_field(outcomes, "passed", passed) @@ -597,7 +596,7 @@ def test_rerun_except_flag(testdir, rerun_except_texts, should_rerun): ], ) def test_rerun_except_and_only_rerun( - testdir, rerun_except_texts, only_rerun_texts, should_rerun + testdir, rerun_except_texts, only_rerun_texts, should_rerun ): testdir.makepyfile('def test_only_rerun_except(): raise ValueError("ERR")') @@ -697,7 +696,7 @@ def test_fail_two(): ], ) def test_only_rerun_flag_in_flaky_marker( - testdir, marker_only_rerun, cli_only_rerun, should_rerun + testdir, marker_only_rerun, cli_only_rerun, should_rerun ): testdir.makepyfile( f""" @@ -717,31 +716,36 @@ def test_fail(): @pytest.mark.parametrize( - "marker_rerun_except,cli_rerun_except,should_rerun", + "marker_rerun_except,cli_rerun_except,raised_error,should_rerun", [ - ("AssertionError", None, False), - ("AssertionError: ERR", None, False), - (["AssertionError"], None, False), - (["AssertionError: ABC"], None, True), - ("ValueError", None, True), - (["ValueError"], None, True), - (["OSError", "ValueError"], None, True), - (["OSError", "AssertionError"], None, False), + ("AssertionError", None, "AssertionError", False), + ("AssertionError: ERR", None, "AssertionError", False), + (["AssertionError"], None, "AssertionError", False), + (["AssertionError: ABC"], None, "AssertionError", True), + ("ValueError", None, "AssertionError", True), + (["ValueError"], None, "AssertionError", True), + (["OSError", "ValueError"], None, "AssertionError", True), + (["OSError", "AssertionError"], None, "AssertionError", False), # CLI override behavior - ("AssertionError", "ValueError", False), - ("ValueError", "AssertionError", True), + ("AssertionError", "ValueError", "AssertionError", False), + ("ValueError", "AssertionError", "AssertionError", True), + ("CustomFailure", None, "CustomFailure", False), + ("CustomFailure", None, "AssertionError", True), ], ) def test_rerun_except_flag_in_flaky_marker( - testdir, marker_rerun_except, cli_rerun_except, should_rerun + testdir, marker_rerun_except, cli_rerun_except, raised_error, should_rerun ): testdir.makepyfile( f""" import pytest + + class CustomFailure(Exception): + pass @pytest.mark.flaky(reruns=1, rerun_except={marker_rerun_except!r}) def test_fail(): - raise AssertionError("ERR") + raise {raised_error}("ERR") """ ) args = []