Asserting warnings with the warns function¶
New in version 2.8.
You can check that code raises a particular warning using
which works in a similar manner to raises:
import warnings import pytest def test_warning(): with pytest.warns(UserWarning): warnings.warn("my warning", UserWarning)
The test will fail if the warning in question is not raised.
You can also call
pytest.warns on a function or code string:
pytest.warns(expected_warning, func, *args, **kwargs) pytest.warns(expected_warning, "func(*args, **kwargs)")
The function also returns a list of all raised warnings (as
warnings.WarningMessage objects), which you can query for
with pytest.warns(RuntimeWarning) as record: warnings.warn("another warning", RuntimeWarning) # check that only one warning was raised assert len(record) == 1 # check that the message matches assert record.message.args == "another warning"
Alternatively, you can examine raised warnings in detail using the recwarn fixture (see below).
You can record raised warnings either using
pytest.warns or with
To record with
pytest.warns without asserting anything about the warnings,
None as the expected warning type:
with pytest.warns(None) as record: warnings.warn("user", UserWarning) warnings.warn("runtime", RuntimeWarning) assert len(record) == 2 assert str(record.message) == "user" assert str(record.message) == "runtime"
recwarn fixture will record warnings for the whole function:
import warnings def test_hello(recwarn): warnings.warn("hello", UserWarning) assert len(recwarn) == 1 w = recwarn.pop(UserWarning) assert issubclass(w.category, UserWarning) assert str(w.message) == "hello" assert w.filename assert w.lineno
pytest.warns return the same interface for recorded
warnings: a WarningsRecorder instance. To view the recorded warnings, you can
iterate over this instance, call
len on it to get the number of recorded
warnings, or index into it to get a particular recorded warning. It also
provides these methods:
A context manager to record raised warnings.
Adapted from warnings.catch_warnings.
The list of recorded warnings.
Pop the first recorded warning, raise exception if not exists.
Clear the list of recorded warnings.
Each recorded warning has the attributes
category is the
class of the warning. The
message is the warning itself; calling
str(message) will return the actual message of the warning.
Ensuring a function triggers a deprecation warning¶
You can also call a global helper for checking
that a certain function call triggers a
import pytest def test_global(): pytest.deprecated_call(myfunction, 17)
By default, deprecation warnings will not be caught when using
recwarn, since the default Python warnings filters hide
DeprecationWarnings. If you wish to record them in your own code, use the
import warnings import pytest def test_deprecation(recwarn): warnings.simplefilter('always') warnings.warn("deprecated", DeprecationWarning) assert len(recwarn) == 1 assert recwarn.pop(DeprecationWarning)