How to test with Python's unittest that a warning has been thrown?
Starting with Python 3.2, you can simply use assertWarns()
method.
with self.assertWarns(Warning): do_something()
You can use the catch_warnings
context manager. Essentially this allows you to mock the warnings handler, so that you can verify details of the warning. See the official docs for a fuller explanation and sample test code.
import warningsdef fxn(): warnings.warn("deprecated", DeprecationWarning)with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger a warning. fxn() # Verify some things assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message)
You can write your own assertWarns function to incapsulate catch_warnings context. I've just implemented it the following way, with a mixin:
class WarningTestMixin(object): 'A test which checks if the specified warning was raised' def assertWarns(self, warning, callable, *args, **kwds): with warnings.catch_warnings(record=True) as warning_list: warnings.simplefilter('always') result = callable(*args, **kwds) self.assertTrue(any(item.category == warning for item in warning_list))
A usage example:
class SomeTest(WarningTestMixin, TestCase): 'Your testcase' def test_something(self): self.assertWarns( UserWarning, your_function_which_issues_a_warning, 5, 10, 'john', # args foo='bar' # kwargs )
The test will pass if at least one of the warnings issued by your_function
is of type UserWarning.