[英]Python unittest - opposite of assertRaises?
我想编写一个测试来确定在给定情况下不会引发异常。
测试是否引发异常很简单......
sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath)
...但你怎么能反其道而行之。
这样的事情我就是我所追求的......
sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath)
def run_test(self):
try:
myFunc()
except ExceptionType:
self.fail("myFunc() raised ExceptionType unexpectedly!")
嗨 - 我想编写一个测试来确定在给定情况下不会引发异常。
这是默认假设——不会引发异常。
如果你什么都不说,那在每一个测试中都是假设的。
您实际上不必为此编写任何断言。
只需调用该函数。 如果它引发异常,单元测试框架会将其标记为错误。 您可能想添加评论,例如:
sValidPath=AlwaysSuppliesAValidPath()
# Check PathIsNotAValidOne not thrown
MyObject(sValidPath)
编辑以添加评论中的说明:
我是原始海报,我接受了 DGH 的上述答案,而没有首先在代码中使用它。
一旦我确实使用了,我意识到它需要稍微调整才能真正做我需要它做的事情(公平地说,他/她确实说过“或类似的东西”!)。
我认为值得在此处发布调整以造福他人:
try:
a = Application("abcdef", "")
except pySourceAidExceptions.PathIsNotAValidOne:
pass
except:
self.assertTrue(False)
我在这里尝试做的是确保如果尝试使用第二个空格参数实例化 Application 对象,则会引发 pySourceAidExceptions.PathIsNotAValidOne 。
我相信使用上面的代码(主要基于 DGH 的答案)会做到这一点。
您可以通过在unittest
模块中重用大约 90% 的assertRaises
原始实现来定义assertNotRaises
。 使用这种方法,您最终会得到一个assertNotRaises
方法,除了其反向失败条件外,其行为与assertRaises
相同。
事实证明,将assertNotRaises
方法添加到unittest.TestCase
非常容易(我编写这个答案的时间是编写代码的时间的 4 倍)。 这是assertNotRaises
方法的现场演示。 就像assertRaises
一样,您可以将 callable 和 args 传递给assertNotRaises
,也可以在with
语句中使用它。 现场演示包括一个测试用例,演示了assertNotRaises
按预期工作。
unittest
中assertRaises
的实现相当复杂,但是通过一些巧妙的子类化,您可以覆盖和逆转其失败条件。
assertRaises
是一个简短的方法,它基本上只是创建unittest.case._AssertRaisesContext
类的一个实例并返回它(参见它在unittest.case
模块中的定义)。 您可以通过子类化_AssertRaisesContext
并覆盖其__exit__
方法来定义自己的_AssertNotRaisesContext
类:
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
方法。
def _assertNotRaises(self, exception, obj, attr):
try:
result = getattr(obj, attr)
if hasattr(result, '__call__'):
result()
except Exception as e:
if isinstance(e, exception):
raise AssertionError('{}.{} raises {}.'.format(obj, attr, exception))
如果需要接受参数可以修改。
呼叫喜欢
self._assertNotRaises(IndexError, array, 'sort')
我发现它是有用的猴子补丁unittest
如下:
def assertMayRaise(self, exception, expr):
if exception is None:
try:
expr()
except:
info = sys.exc_info()
self.fail('%s raised' % repr(info[0]))
else:
self.assertRaises(exception, expr)
unittest.TestCase.assertMayRaise = assertMayRaise
这在测试是否存在异常时阐明了意图:
self.assertMayRaise(None, does_not_raise)
这也简化了循环中的测试,我经常发现自己在这样做:
# ValueError is raised only for op(x,x), op(y,y) and op(z,z).
for i,(a,b) in enumerate(itertools.product([x,y,z], [x,y,z])):
self.assertMayRaise(None if i%4 else ValueError, lambda: op(a, b))
你可以这样试试。 try: self.assertRaises(None,function,arg1, arg2) except: pass 如果你不把代码放在 try 块中,它将通过异常' AssertionError: None not raise "并且测试用例将失败。测试用例将通过如果放在 try 块中,这是预期的行为。
如果您将 Exception 类传递给assertRaises()
,则会提供上下文管理器。 这可以提高测试的可读性:
# raise exception if Application created with bad data
with self.assertRaises(pySourceAidExceptions.PathIsNotAValidOne):
application = Application("abcdef", "")
这允许您测试代码中的错误情况。
在这种情况下,您正在测试PathIsNotAValidOne
是否在您将无效参数传递给 Application 构造函数时引发。
确保对象初始化没有任何错误的一种直接方法是测试对象的类型实例。
这是一个例子:
p = SomeClass(param1=_param1_value)
self.assertTrue(isinstance(p, SomeClass))
我想编写一个测试来确定在给定的情况下不引发异常。
测试是否引发异常很简单...
sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath)
...但是你怎么做相反。
像这样的东西我在追求...
sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.