Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does @pytest.mark.filterwarnings work?

Tags:

python

pytest

According to the docs you can ignore warnings like this:

@pytest.mark.filterwarnings("ignore:api v1")
def test_foo():

which gives:

But there doesn't seem to be any documentation on this mini-language (is it even a minilanguage?)

How is the match done?

I'm asking this because the following test doesn't ignore the DeprecationWarning raised by importing boto3:

@pytest.mark.filterwarnings("ignore:DeprecationWarning")
def test_ignore_warnings():
    import boto3

Pytest outputs:

============================================================================================================================== warnings summary ===============================================================================================================================
/home/rob/dev/time-series/.venv/lib/python3.7/site-packages/botocore/awsrequest.py:624
  /home/rob/dev/time-series/.venv/lib/python3.7/site-packages/botocore/awsrequest.py:624: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
    class HeadersDict(collections.MutableMapping):

-- Docs: https://docs.pytest.org/en/latest/warnings.html
==================================================================================================================== 1 passed, 1 warnings in 0.36 seconds =====================================================================================================================
like image 577
LondonRob Avatar asked Oct 31 '19 14:10

LondonRob


Video Answer


1 Answers

The filters work the same way as when you use -W argument with python command (see python --help). The format is described in the documentation of the warnings module. In short it's action:message:category:module:line where action is probably mandatory but the other parts can be omitted.

"ignore:api v1" would try to match the message by defining "a string containing a regular expression that the start of the warning message must match". Since you actually want to match category you can skip message. This means that you just seem to be missing one colon after ignore so this is the correct format:

@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_ignore_warnings():
    import boto3

However, you might apparently still get the warning if it happens during an import of a package outside of a test function. In this case you might need to specify the filter globally as a pytest's argument:

pytest -W "ignore::DeprecationWarning" ./tests/

...or add it to pytest.ini:

[pytest]
filterwarnings =
    ignore::DeprecationWarning

If such a global exclusion is undesirable, you can try to limit it to a particular module:

ignore::DeprecationWarning:boto3

Testing

For testing purposes, you can use the following code:

import warnings

def something():
    warnings.warn("Test", DeprecationWarning)

@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_ignore_warnings():
    something()
like image 98
tmt Avatar answered Oct 07 '22 05:10

tmt