diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 4b61db4968a..29136be6708 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -268,15 +268,19 @@ def __exit__( __tracebackhide__ = True + def found_str(): + found = "".join(f" {each.message!r},\n" for each in self) + return f"\n{found}" if found else "" + # only check if we're not currently handling an exception if exc_type is None and exc_val is None and exc_tb is None: if self.expected_warning is not None: if not any(issubclass(r.category, self.expected_warning) for r in self): __tracebackhide__ = True fail( - "DID NOT WARN. No warnings of type {} was emitted. " - "The list of emitted warnings is: {}.".format( - self.expected_warning, [each.message for each in self] + "DID NOT WARN. No warnings of type {expected} was emitted. " + "The list of emitted warnings is: [{found}].".format( + expected=self.expected_warning, found=found_str() ) ) elif self.match_expr is not None: @@ -286,11 +290,13 @@ def __exit__( break else: fail( - "DID NOT WARN. No warnings of type {} matching" - " ('{}') was emitted. The list of emitted warnings" - " is: {}.".format( - self.expected_warning, - self.match_expr, - [each.message for each in self], + "DID NOT WARN. No warnings of type {expected} matching the" + " regex was emitted.\n" + "The regex is: {match!r}\n" + "The list of emitted warnings" + " is: [{found}].".format( + expected=self.expected_warning, + match=self.match_expr, + found=found_str(), ) ) diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 40a2e23fa6c..50c0f33e951 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -1,4 +1,3 @@ -import re import warnings from typing import Optional @@ -251,23 +250,25 @@ def test_as_contextmanager(self) -> None: with pytest.raises(pytest.fail.Exception) as excinfo: with pytest.warns(RuntimeWarning): warnings.warn("user", UserWarning) - excinfo.match( + assert excinfo.match( r"DID NOT WARN. No warnings of type \(.+RuntimeWarning.+,\) was emitted. " - r"The list of emitted warnings is: \[UserWarning\('user',?\)\]." + r"The list of emitted warnings is: \[\n" + r" UserWarning\('user'\),\n" + r"\]." ) with pytest.raises(pytest.fail.Exception) as excinfo: with pytest.warns(UserWarning): warnings.warn("runtime", RuntimeWarning) - excinfo.match( + assert excinfo.match( r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) was emitted. " - r"The list of emitted warnings is: \[RuntimeWarning\('runtime',?\)\]." + r"The list of emitted warnings is: \[\n RuntimeWarning\('runtime',?\),\n\]." ) with pytest.raises(pytest.fail.Exception) as excinfo: with pytest.warns(UserWarning): pass - excinfo.match( + assert excinfo.match( r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) was emitted. " r"The list of emitted warnings is: \[\]." ) @@ -280,14 +281,11 @@ def test_as_contextmanager(self) -> None: message_template = ( "DID NOT WARN. No warnings of type {0} was emitted. " - "The list of emitted warnings is: {1}." + "The list of emitted warnings is: [\n{1}]." ) - excinfo.match( - re.escape( - message_template.format( - warning_classes, [each.message for each in warninfo] - ) - ) + + assert str(excinfo.value) == message_template.format( + warning_classes, "".join(f" {each.message!r},\n" for each in warninfo) ) def test_record(self) -> None: