Python의 unittest로 경고가 발생했는지 테스트하는 방법은 무엇입니까?
Python에 다음 함수가 있으며 함수가 0을 인수로 가져 오면 경고가 발생하는지 unittest로 테스트하고 싶습니다. 나는 이미 assertRaises를 시도했지만 경고를 제기하지 않았기 때문에 작동하지 않습니다.
def isZero(i):
if i != 0:
print "OK"
else:
warning = Warning("the input is 0!")
print warning
return i
catch_warnings
컨텍스트 관리자를 사용할 수 있습니다 . 기본적으로이를 통해 경고 처리기를 모의 처리하여 경고의 세부 정보를 확인할 수 있습니다. 자세한 설명과 샘플 테스트 코드 는 공식 문서 를 참조하십시오 .
import warnings
def 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)
Python 3.2부터는 간단히 assertWarns()
메소드 를 사용할 수 있습니다 .
with self.assertWarns(Warning):
do_something()
catch_warnings 컨텍스트를 캡슐화하기 위해 자신의 assertWarns 함수를 작성할 수 있습니다. 믹스 인을 사용하여 다음과 같은 방식으로 구현했습니다.
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))
사용 예 :
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.
@ire_and_curses' answer is quite useful and, I think, canonical. Here is another way to do the same thing. This one requires Michael Foord's excellent Mock
library.
import unittest, warnings
from mock import patch_object
def isZero( i):
if i != 0:
print "OK"
else:
warnings.warn( "the input is 0!")
return i
class Foo(unittest.TestCase):
@patch_object(warnings, 'warn')
def test_is_zero_raises_warning(self, mock_warn):
isZero(0)
self.assertTrue(mock_warn.called)
if __name__ == '__main__':
unittest.main()
The nifty patch_object
lets you mock out the warn
method.
One problem with the warnings.catch_warnings
approach is that warnings produced in different tests can interact in strange ways through global state kept in __warningregistry__
attributes.
To address this, we should clear the __warningregistry__
attribute of every module before every test that checks warnings.
class MyTest(unittest.TestCase):
def setUp(self):
# The __warningregistry__'s need to be in a pristine state for tests
# to work properly.
for v in sys.modules.values():
if getattr(v, '__warningregistry__', None):
v.__warningregistry__ = {}
def test_something(self):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always", MySpecialWarning)
...
self.assertEqual(len(w), 1)
self.assertIsInstance(w[0].message, MySpecialWarning)
This is how Python 3's assertWarns()
method is implemented.
ReferenceURL : https://stackoverflow.com/questions/3892218/how-to-test-with-pythons-unittest-that-a-warning-has-been-thrown
'Programing' 카테고리의 다른 글
Apple Interface Builder : UIImageView에 하위보기 추가 (0) | 2021.01.11 |
---|---|
콘텐츠로 HTML5 캔버스 요소를 복제하는 방법은 없나요? (0) | 2021.01.11 |
장고를 배우는 가장 좋은 방법은 무엇입니까? (0) | 2021.01.11 |
기능 용 오토로더 (0) | 2021.01.11 |
빠르고 명시적인 예제에서 편의성 init와 init의 차이점은 무엇입니까? (0) | 2021.01.10 |