Test a warning without hiding unrelated warning categories
Also published in our primary archive.
A direct answer to “Test a warning without hiding unrelated warning categories Python” is: assert the warning category you expect, then use a temporary recording context to inspect other categories that matter. Avoid a broad global ignore filter, because it can remove evidence the test ought to inspect.
The fixture first uses assertWarns(UserWarning) for a selected warning. Its context object exposes the warning instance, so the assertion checks that instance with assertIsInstance rather than assuming it has a nonexistent category attribute. A separate warnings.catch_warnings(record=True) block records both a UserWarning and a DeprecationWarning after the local action is set to always. The result explicitly proves that the second category remained observable in this controlled block.
The final equality check verifies that this fixture’s warning filters match their prior values after the context exits. It does not prove that every library or concurrent task uses warnings identically; warning handling can depend on runtime configuration and Python version. Keep filter changes narrowly scoped and test the categories that affect the behavior under examination. assertWarns was added in Python 3.2. Consult the official assertWarns documentation and the catch_warnings documentation.
AI assistance disclosure: this synthetic warning example was drafted with AI assistance.
import unittest
import warnings
case = unittest.TestCase()
filters_before = list(warnings.filters)
with case.assertWarns(UserWarning) as selected:
warnings.warn("selected", UserWarning)
case.assertIsInstance(selected.warning, UserWarning)
with warnings.catch_warnings(record=True) as recorded:
warnings.simplefilter("always")
warnings.warn("selected-again", UserWarning)
warnings.warn("still-visible", DeprecationWarning)
categories = [item.category for item in recorded]
case.assertEqual(categories, [UserWarning, DeprecationWarning])
case.assertEqual(warnings.filters, filters_before)
print(f"selected={selected.warning.__class__.__name__}")
print(f"other={categories[1].__name__}")
print("filters=restored")
selected=UserWarning
other=DeprecationWarning
filters=restored