我想编写一个测试,以确定在给定的情况下不会引发异常。

测试是否引发异常是很简单的…

sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath) 

... 但你怎么能反其道而行之呢。

像这样的东西是我所追求的…

sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath) 

当前回答

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模块中90%的assertRaises原始实现来定义assertNotRaises。使用这种方法,您最终得到一个assertNotRaises方法,除了它的反向失败条件外,它的行为与assertRaises完全相同。

TLDR和现场演示

在unittest中添加assertNotRaises方法非常简单。TestCase(写这个答案的时间是写代码的4倍)。下面是assertNotRaises方法的现场演示。就像assertRaises一样,你可以传递一个可调用对象和参数给assertNotRaises,或者你可以在with语句中使用它。现场演示包括一个测试用例,演示assertNotRaises按预期工作。

细节

在unittest中实现assertRaises是相当复杂的,但是通过一些聪明的子类化,你可以覆盖和逆转它的失败条件。

assertRaises是一个简短的方法,基本上只创建unittest.case的一个实例。_AssertRaisesContext类并返回它(参见unittest. context中的定义)。模块)。你可以通过继承_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方法可用。

如果您将一个Exception类传递给assertRaises(),则会提供一个上下文管理器。这可以提高测试的可读性:

# raise exception if Application created with bad data
with self.assertRaises(pySourceAidExceptions.PathIsNotAValidOne):
    application = Application("abcdef", "")

这允许您测试代码中的错误用例。

在本例中,您正在测试将无效参数传递给应用程序构造函数时引发PathIsNotAValidOne。

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')
def run_test(self):
    try:
        myFunc()
    except ExceptionType:
        self.fail("myFunc() raised ExceptionType unexpectedly!")