关于python:如何获取unittest中抛出的异常

How to get the exception thrown in unittest

我有自己的例外,我想测试ex中的更远的字段然后消息。
阅读这个帖子我尝试了使用上下文的想法。 我写了这个通用函数

1
2
3
4
5
6
7
8
9
def test_runtime_error(test, exception_type, message, display_parameter, path, callable_obj, *args):
    pdb.set_trace()
    with test.assertRaises(exception_type) as cx:
        callable_obj(*args)
    ex = cx.exception

    test.assertEqual(ex.message,message)
    test.assertEqual(ex.display_parameter,display_parameter)
    test.assertEqual(ex.path,path)

pathdisplay_parameter是我自己的特定字段。 我不是在这里发明轮子,我从源头上拿走了它的大部分。

我正在那样使用它

1
2
3
4
5
class ExceptionsTest(unittest.TestCase):
    def test_something(self):
         data = {"name" :"A"}
         obj = MyModel.objects.get(pk=1)
         test_runtime_error(self,CustomException, 'message', 'A', [], obj.create, data)

参数正确传递给callable_obj。 该函数引发了预期的异常。 但是在执行callable_obj之后,函数就会中断并且不会获取异常。 顺便说一句,当我在测试中运行相同的代码时,它自己运行正常。

这里有什么不对?


这里的问题似乎是这一行:

1
pdb.set_trace()

如果您将其保留,但没有import pdb,则以下代码将失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
E
======================================================================
ERROR: testRaises (__main__.ExceptionTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File"./except.py", line 22, in testRaises
    self.verifyComplexException(MyException, 'asdf', RaiseException, 'asdf')
  File"./except.py", line 14, in verifyComplexException
    pdb.set_trace()
NameError: global name 'pdb' is not defined

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

符合您的描述。 如果你确实添加了import pdb行,它将进入调试器,这是一个完全不同的行为,不能混淆退出E或退出F状态,所以不能这样。

这是一个基于这个想法的完整示例,它按预期工作(在Apache 2.0下获得许可;请参阅我的回购):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import unittest

class MyException(Exception):
    def __init__(self, message):
        self.message = message

def RaiseException(message):
    raise MyException(message)

class ExceptionTest(unittest.TestCase):
    def verifyComplexException(self, exception_class, message, callable, *args):
        with self.assertRaises(exception_class) as cm:
            callable(*args)

        exception = cm.exception
        self.assertEqual(exception.message, message)

    def testRaises(self):
        self.verifyComplexException(MyException, 'asdf', RaiseException, 'asdf')


if __name__ == '__main__':
    unittest.main()