diff --git a/pandas/_testing/_warnings.py b/pandas/_testing/_warnings.py index 5153118e9b142..5f01996d0390d 100644 --- a/pandas/_testing/_warnings.py +++ b/pandas/_testing/_warnings.py @@ -106,6 +106,7 @@ def _assert_caught_expected_warning( """Assert that there was the expected warning among the caught warnings.""" saw_warning = False matched_message = False + unmatched_messages = [] for actual_warning in caught_warnings: if issubclass(actual_warning.category, expected_warning): @@ -116,8 +117,11 @@ def _assert_caught_expected_warning( ): _assert_raised_with_correct_stacklevel(actual_warning) - if match is not None and re.search(match, str(actual_warning.message)): - matched_message = True + if match is not None: + if re.search(match, str(actual_warning.message)): + matched_message = True + else: + unmatched_messages.append(actual_warning.message) if not saw_warning: raise AssertionError( @@ -128,7 +132,8 @@ def _assert_caught_expected_warning( if match and not matched_message: raise AssertionError( f"Did not see warning {repr(expected_warning.__name__)} " - f"matching {match}" + f"matching '{match}'. The emitted warning messages are " + f"{unmatched_messages}" ) diff --git a/pandas/tests/util/test_assert_produces_warning.py b/pandas/tests/util/test_assert_produces_warning.py index 45699fa1294d3..e3eb083e1a383 100644 --- a/pandas/tests/util/test_assert_produces_warning.py +++ b/pandas/tests/util/test_assert_produces_warning.py @@ -94,19 +94,49 @@ def test_catch_warning_category_and_match(category, message, match): warnings.warn(message, category) -@pytest.mark.parametrize( - "message, match", - [ - ("Warning message", "Not this message"), - ("Warning message", "warning"), - ("Warning message", r"\d+"), - ], -) -def test_fail_to_match(category, message, match): - msg = f"Did not see warning {repr(category.__name__)} matching" - with pytest.raises(AssertionError, match=msg): +def test_fail_to_match_runtime_warning(): + category = RuntimeWarning + match = "Did not see this warning" + unmatched = ( + r"Did not see warning 'RuntimeWarning' matching 'Did not see this warning'. " + r"The emitted warning messages are " + r"\[RuntimeWarning\('This is not a match.'\), " + r"RuntimeWarning\('Another unmatched warning.'\)\]" + ) + with pytest.raises(AssertionError, match=unmatched): + with tm.assert_produces_warning(category, match=match): + warnings.warn("This is not a match.", category) + warnings.warn("Another unmatched warning.", category) + + +def test_fail_to_match_future_warning(): + category = FutureWarning + match = "Warning" + unmatched = ( + r"Did not see warning 'FutureWarning' matching 'Warning'. " + r"The emitted warning messages are " + r"\[FutureWarning\('This is not a match.'\), " + r"FutureWarning\('Another unmatched warning.'\)\]" + ) + with pytest.raises(AssertionError, match=unmatched): + with tm.assert_produces_warning(category, match=match): + warnings.warn("This is not a match.", category) + warnings.warn("Another unmatched warning.", category) + + +def test_fail_to_match_resource_warning(): + category = ResourceWarning + match = r"\d+" + unmatched = ( + r"Did not see warning 'ResourceWarning' matching '\\d\+'. " + r"The emitted warning messages are " + r"\[ResourceWarning\('This is not a match.'\), " + r"ResourceWarning\('Another unmatched warning.'\)\]" + ) + with pytest.raises(AssertionError, match=unmatched): with tm.assert_produces_warning(category, match=match): - warnings.warn(message, category) + warnings.warn("This is not a match.", category) + warnings.warn("Another unmatched warning.", category) def test_fail_to_catch_actual_warning(pair_different_warnings):