I'm writing unit tests using nose, and I'd like to check whether a function raises a warning (the function uses warnings.warn
). Is this something that can easily be done?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
def your_code():
# ...
warnings.warn("deprecated", DeprecationWarning)
# ...
def your_test():
with warnings.catch_warnings(record=True) as w:
your_code()
assert len(w) > 1
Instead of just checking the lenght, you can check it in-depth, of course:
assert str(w.args[0]) == "deprecated"
In python 2.7 or later, you can do this with the last check as:
assert str(w[0].message[0]) == "deprecated"
回答2:
There are (at least) two ways of doing this. You can catch the warning in the list
of warnings.WarningMessage
s in test or use mock
to patch
the imported warnings
in your module.
I think the patch
version is more general.
raise_warning.py:
import warnings
def should_warn():
warnings.warn('message', RuntimeWarning)
print('didn\'t I warn you?')
raise_warning_tests.py:
import unittest
from mock import patch
import raise_warning
class TestWarnings(unittest.TestCase):
@patch('raise_warning.warnings.warn')
def test_patched(self, mock_warnings):
"""test with patched warnings"""
raise_warning.should_warn()
self.assertTrue(mock_warnings.called)
def test_that_catches_warning(self):
"""test by catching warning"""
with raise_warning.warnings.catch_warnings(True) as wrn:
raise_warning.should_warn()
# per-PEP8 check for empty sequences by their Truthiness
self.assertTrue(wrn)