Skip to content

Commit cbceef2

Browse files
Merge pull request #2598 from nicoddemus/filterwarnings-mark
Introduce filter-warnings mark
2 parents abb5d20 + 7341da1 commit cbceef2

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

_pytest/warnings.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ def catch_warnings_for_item(item):
5959
for arg in inifilters:
6060
_setoption(warnings, arg)
6161

62+
mark = item.get_marker('filterwarnings')
63+
if mark:
64+
for arg in mark.args:
65+
warnings._setoption(arg)
66+
6267
yield
6368

6469
for warning in log:

changelog/2598.feature

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

doc/en/warnings.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,40 @@ Both ``-W`` command-line option and ``filterwarnings`` ini option are based on P
7878
`-W option`_ and `warnings.simplefilter`_, so please refer to those sections in the Python
7979
documentation for other examples and advanced usage.
8080

81+
``@pytest.mark.filterwarnings``
82+
-------------------------------
83+
84+
.. versionadded:: 3.2
85+
86+
You can use the ``@pytest.mark.filterwarnings`` to add warning filters to specific test items,
87+
allowing you to have finer control of which warnings should be captured at test, class or
88+
even module level:
89+
90+
.. code-block:: python
91+
92+
import warnings
93+
94+
def api_v1():
95+
warnings.warn(UserWarning("api v1, should use functions from v2"))
96+
return 1
97+
98+
@pytest.mark.filterwarnings('ignore:api v1')
99+
def test_one():
100+
assert api_v1() == 1
101+
102+
103+
Filters applied using a mark take precedence over filters passed on the command line or configured
104+
by the ``filterwarnings`` ini option.
105+
106+
You may apply a filter to all tests of a class by using the ``filterwarnings`` mark as a class
107+
decorator or to all tests in a module by setting the ``pytestmark`` variable:
108+
109+
.. code-block:: python
110+
111+
# turns all warnings into errors for this module
112+
pytestmark = @pytest.mark.filterwarnings('error')
113+
114+
81115
.. note::
82116

83117
``DeprecationWarning`` and ``PendingDeprecationWarning`` are hidden by the standard library

testing/test_warnings.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,32 @@ def test_my_warning(self):
188188
result.stdout.fnmatch_lines([
189189
'*== 1 passed in *',
190190
])
191+
192+
193+
@pytest.mark.parametrize('default_config', ['ini', 'cmdline'])
194+
def test_filterwarnings_mark(testdir, default_config):
195+
"""
196+
Test ``filterwarnings`` mark works and takes precedence over command line and ini options.
197+
"""
198+
if default_config == 'ini':
199+
testdir.makeini("""
200+
[pytest]
201+
filterwarnings = always
202+
""")
203+
testdir.makepyfile("""
204+
import warnings
205+
import pytest
206+
207+
@pytest.mark.filterwarnings('ignore::RuntimeWarning')
208+
def test_ignore_runtime_warning():
209+
warnings.warn(RuntimeWarning())
210+
211+
@pytest.mark.filterwarnings('error')
212+
def test_warning_error():
213+
warnings.warn(RuntimeWarning())
214+
215+
def test_show_warning():
216+
warnings.warn(RuntimeWarning())
217+
""")
218+
result = testdir.runpytest('-W always' if default_config == 'cmdline' else '')
219+
result.stdout.fnmatch_lines(['*= 1 failed, 2 passed, 1 warnings in *'])

0 commit comments

Comments
 (0)