'Make pytest fail on ResourceWarning (unclosed files)
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?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
