How to test with Python's unittest that a warning has been thrown? How to test with Python's unittest that a warning has been thrown? python python

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.