您可以定义assertNotRaises
通过重用对原执行的90%assertRaises
的中unittest
模块。使用这种方法,最终得到的assertNotRaises
方法除了其反向失败条件外,其行为与相同assertRaises
。
TLDR和现场演示
事实证明,向其中添加assertNotRaises
方法非常容易unittest.TestCase
(编写此答案所花的时间是代码的四倍,这使我花了大约四倍的时间)。这是该assertNotRaises
方法的现场演示。就像一样assertRaises
,您可以将callable和args传递给assertNotRaises
,也可以在with
语句中使用它。现场演示包括一个测试案例,演示了assertNotRaises
预期的工作方式。
细节
assertRaises
in 的实现unittest
相当复杂,但是通过一些巧妙的子类化,您可以覆盖和逆转其失败条件。
assertRaises
是一个简短的方法,基本上只创建unittest.case._AssertRaisesContext
类的实例并返回它(请参见unittest.case
模块中的定义)。您可以_AssertNotRaisesContext
通过继承_AssertRaisesContext
并覆盖其__exit__
方法来定义自己的类:
import traceback
from unittest.case import _AssertRaisesContext
class _AssertNotRaisesContext(_AssertRaisesContext):
def __exit__(self, exc_type, exc_value, tb):
if exc_type is not None:
self.exception = exc_value.with_traceback(None)
try:
exc_name = self.expected.__name__
except AttributeError:
exc_name = str(self.expected)
if self.obj_name:
self._raiseFailure("{} raised by {}".format(exc_name,
self.obj_name))
else:
self._raiseFailure("{} raised".format(exc_name))
else:
traceback.clear_frames(tb)
return True
通常,您可以通过从中继承来定义测试用例类TestCase
。如果您改为继承子类MyTestCase
:
class MyTestCase(unittest.TestCase):
def assertNotRaises(self, expected_exception, *args, **kwargs):
context = _AssertNotRaisesContext(expected_exception, self)
try:
return context.handle('assertNotRaises', args, kwargs)
finally:
context = None
现在,您所有的测试用例都将具有assertNotRaises
可用的方法。