diff --git a/changelog/9404.doc.rst b/changelog/9404.doc.rst new file mode 100644 index 00000000000..70e4c6d5899 --- /dev/null +++ b/changelog/9404.doc.rst @@ -0,0 +1 @@ +Added extra documentation on alternatives to common misuses of `pytest.warns(None)` ahead of its deprecation. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 6351d1f6e6a..a667fc4ccdf 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -221,11 +221,11 @@ Using ``pytest.warns(None)`` .. deprecated:: 7.0 -:func:`pytest.warns(None) ` is now deprecated because many people used -it to mean "this code does not emit warnings", but it actually had the effect of -checking that the code emits at least one warning of any type - like ``pytest.warns()`` +:func:`pytest.warns(None) ` is now deprecated because it was frequently misused. +Its correct usage was checking that the code emits at least one warning of any type - like ``pytest.warns()`` or ``pytest.warns(Warning)``. +See :ref:`warns use cases` for examples. The ``--strict`` command-line option ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/en/how-to/capture-warnings.rst b/doc/en/how-to/capture-warnings.rst index 7e877b4d3da..81f2ebd6ea5 100644 --- a/doc/en/how-to/capture-warnings.rst +++ b/doc/en/how-to/capture-warnings.rst @@ -344,6 +344,35 @@ warnings, or index into it to get a particular recorded warning. Full API: :class:`~_pytest.recwarn.WarningsRecorder`. +.. _`warns use cases`: + +Additional use cases of warnings in tests +----------------------------------------- + +Here are some use cases involving warnings that often come up in tests, and suggestions on how to deal with them: + +- To ensure that **any** warning is emitted, use: + +.. code-block:: python + + with pytest.warns(): + pass + +- To ensure that **no** warnings are emitted, use: + +.. code-block:: python + + with warnings.catch_warnings(): + warnings.simplefilter("error") + +- To suppress warnings, use: + +.. code-block:: python + + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + + .. _custom_failure_messages: Custom failure messages diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index f68aea37e4d..4534fbcab82 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -88,8 +88,10 @@ ) WARNS_NONE_ARG = PytestRemovedIn8Warning( - "Passing None to catch any warning has been deprecated, pass no arguments instead:\n" - " Replace pytest.warns(None) by simply pytest.warns()." + "Passing None has been deprecated.\n" + "See https://docs.pytest.org/en/latest/how-to/capture-warnings.html" + "#additional-use-cases-of-warnings-in-tests" + " for alternatives in common use cases." ) KEYWORD_MSG_ARG = UnformattedWarning( diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index c316b074c4b..a567201b222 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -138,8 +138,10 @@ def test_warns_none_is_deprecated(): with pytest.warns( PytestDeprecationWarning, match=re.escape( - "Passing None to catch any warning has been deprecated, pass no arguments instead:\n " - "Replace pytest.warns(None) by simply pytest.warns()." + "Passing None has been deprecated.\n" + "See https://docs.pytest.org/en/latest/how-to/capture-warnings.html" + "#additional-use-cases-of-warnings-in-tests" + " for alternatives in common use cases." ), ): with pytest.warns(None): # type: ignore[call-overload]