【问题标题】:How to get the exception thrown in unittest如何获取单元测试中抛出的异常
【发布时间】:2014-01-17 07:47:23
【问题描述】:

我有自己的例外情况,我想测试除消息之外的其他字段。 阅读此thread 我尝试了使用上下文的想法。我写了这个通用函数

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 是我自己的特定字段。我不是在这里发明轮子,我从source 获取了大部分内容。

我就是这样用的

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 执行之后,函数会中断并且不会获取异常。顺便说一句,当我在测试中运行相同的代码时,它运行良好。

这里有什么问题吗?

【问题讨论】:

  • 我会改为创建一个基础 TestCase 类并在其上引入 test_runtime_error 作为方法。
  • “函数中断,异常没有被获取”——那么发生了什么
  • @shx2 测试中断 - 异常 E - 不是测试失败 F
  • @alecxe - 会有所作为吗? (其他然后更整洁...?)
  • 您的测试失败的确切异常是什么?请在问题中添加完整的输出。如果删除 pdb.set_trace() 行会发生什么?

标签: python django unit-testing


【解决方案1】:

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

pdb.set_trace()

如果你把它留在里面,但没有import pdb,下面的代码将会失败:

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 下获得许可;请参阅 my repo):

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多