Introduce pytest.mark.filterwarnings

This commit is contained in:
Bruno Oliveira 2017-07-20 22:02:21 -03:00
parent abb5d20841
commit 7341da1bc1
4 changed files with 70 additions and 0 deletions

View File

@ -59,6 +59,11 @@ def catch_warnings_for_item(item):
for arg in inifilters: for arg in inifilters:
_setoption(warnings, arg) _setoption(warnings, arg)
mark = item.get_marker('filterwarnings')
if mark:
for arg in mark.args:
warnings._setoption(arg)
yield yield
for warning in log: for warning in log:

2
changelog/2598.feature Normal file
View File

@ -0,0 +1,2 @@
Introduced ``@pytest.mark.filterwarnings`` mark which allows overwriting the warnings filter on a per test, class or module level.
See the `docs <https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings>`_ for more information.

View File

@ -78,6 +78,40 @@ Both ``-W`` command-line option and ``filterwarnings`` ini option are based on P
`-W option`_ and `warnings.simplefilter`_, so please refer to those sections in the Python `-W option`_ and `warnings.simplefilter`_, so please refer to those sections in the Python
documentation for other examples and advanced usage. documentation for other examples and advanced usage.
``@pytest.mark.filterwarnings``
-------------------------------
.. versionadded:: 3.2
You can use the ``@pytest.mark.filterwarnings`` to add warning filters to specific test items,
allowing you to have finer control of which warnings should be captured at test, class or
even module level:
.. code-block:: python
import warnings
def api_v1():
warnings.warn(UserWarning("api v1, should use functions from v2"))
return 1
@pytest.mark.filterwarnings('ignore:api v1')
def test_one():
assert api_v1() == 1
Filters applied using a mark take precedence over filters passed on the command line or configured
by the ``filterwarnings`` ini option.
You may apply a filter to all tests of a class by using the ``filterwarnings`` mark as a class
decorator or to all tests in a module by setting the ``pytestmark`` variable:
.. code-block:: python
# turns all warnings into errors for this module
pytestmark = @pytest.mark.filterwarnings('error')
.. note:: .. note::
``DeprecationWarning`` and ``PendingDeprecationWarning`` are hidden by the standard library ``DeprecationWarning`` and ``PendingDeprecationWarning`` are hidden by the standard library

View File

@ -188,3 +188,32 @@ def test_works_with_filterwarnings(testdir):
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
'*== 1 passed in *', '*== 1 passed in *',
]) ])
@pytest.mark.parametrize('default_config', ['ini', 'cmdline'])
def test_filterwarnings_mark(testdir, default_config):
"""
Test ``filterwarnings`` mark works and takes precedence over command line and ini options.
"""
if default_config == 'ini':
testdir.makeini("""
[pytest]
filterwarnings = always
""")
testdir.makepyfile("""
import warnings
import pytest
@pytest.mark.filterwarnings('ignore::RuntimeWarning')
def test_ignore_runtime_warning():
warnings.warn(RuntimeWarning())
@pytest.mark.filterwarnings('error')
def test_warning_error():
warnings.warn(RuntimeWarning())
def test_show_warning():
warnings.warn(RuntimeWarning())
""")
result = testdir.runpytest('-W always' if default_config == 'cmdline' else '')
result.stdout.fnmatch_lines(['*= 1 failed, 2 passed, 1 warnings in *'])