Reputation: 5167
Some of my tests need to ensure open files are closed. Let's use the simplest example:
# test_example.py
import pytest
@pytest.mark.filterwarnings('error::ResourceWarning')
def test_resourcewarning():
open('/dev/null')
When I run pytest
, the warning is thrown and even printed in the test output, but the test still passes:
$ pytest
============================ test session starts =============================
platform darwin -- Python 3.10.2, pytest-7.1.1, pluggy-1.0.0
rootdir: /path/to/project
collected 1 item
test_example.py . [100%]
============================== warnings summary ==============================
test_example.py::test_resourcewarning
/path/to/python/site-packages/_pytest/unraisableexception.py:78: PytestUnrai
sableExceptionWarning: Exception ignored in: <_io.FileIO [closed]>
Traceback (most recent call last):
File "/path/to/project/test_example.py", line 5, in test_resourcewarning
open('/dev/null')
ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r'
encoding='UTF-8'>
warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================== 1 passed, 1 warning in 0.01s ========================
Removing @pytest.mark.filterwarnings
or changing the warning type to something unrelated (like DeprecationWarning
) results in the test passing without printing any warnings at all, so clearly this is catching the warning - but it seems to be subsequently caught by pytest. Pytest then throws pytest.PytestUnraisableExceptionWarning
, which doesn't fail because I wasn't filtering for that. If I do filter for pytest.PytestUnraisableExceptionWarning
the test also passes, because it isn't looking for the original ResourceWarning
.
The only solution I can think of is to filter for both:
@pytest.mark.filterwarnings('error::ResourceWarning')
@pytest.mark.filterwarnings('error::pytest.PytestUnraisableExceptionWarning')
But at this point it doesn't make any sense to me, even after trawling through docs and google search results I don't understand how filtering for warnings is supposed to work if pytest is just going to swallow them and make me capture its own warnings to actually register a test failure, and so the only logical conclusion is that I don't know what I'm doing (or that this is a bug).
What am I missing?
Upvotes: 7
Views: 1989
Reputation: 42659
I recently learned that ResourceWarning
s are ignored by default. In jaraco/skeleton (from which I derive my projects), I've added this commit to enable warnings by default, essentially adding the following to pytest.ini:
[pytest]
filterwarnings =
default::ResourceWarning
Use error
instead of default
to enable the errors by default across the project.
Upvotes: 2
Reputation: 2136
Try this:
#test_example.py
import pytest
@pytest.mark.filterwarnings("error")
def test_resourcewarning():
open('/dev/null')
This makes the test fail for me:
Taken from the pytest docs (https://docs.pytest.org/en/stable/how-to/capture-warnings.html#pytest-mark-filterwarnings)
Upvotes: 2