【问题标题】:python unittest assertRaises throws exception when assertRaises failspython unittest assertRaises在assertRaises失败时抛出异常
【发布时间】:2009-08-04 23:51:42
【问题描述】:

我有代码,当 assertRaises 失败时,assertRaises 会抛出异常。我认为如果 assertRaises 失败,那么测试就会失败,最后我会得到一份报告说测试失败。我没想到会抛出异常。下面是我的代码。我做错了什么?我正在使用 Python 2.6.2。

import unittest

class myClass:

    def getName(self):

        raise myExcOne, "my exception one"
        #raise myExcTwo, "my exception two"
        #return "a"

class myExcOne(Exception):
    "exception one"

class myExcTwo(Exception):
    "exception two"


class test_myClass(unittest.TestCase):

    def setUp(self):

        self.myClass = myClass()

    def testgetNameEmpty(self):
        #self.assertRaises(myExcOne,self.myClass.getName)
        #self.assertRaises(myExcTwo,self.myClass.getName)

        try:
            self.assertRaises(myExcTwo,self.myClass.getName)
        except Exception as e:
            pass

if __name__ == "__main__":

    #unittest.main()

    suite = unittest.TestLoader().loadTestsFromTestCase(test_myClass)
    unittest.TextTestRunner(verbosity=2).run(suite)

【问题讨论】:

  • 您所说的“断言失败”具体是什么意思?您可以发布堆栈跟踪或错误消息吗?
  • 我重新阅读文档并在 assertRaises 失败时抛出异常是预期的行为。我误解了该工具的工作原理。我忘了在上一篇文章中提到这一点。如果我发现异常,报告会告诉我测试通过了,即使它没有。我已经更新了我的代码

标签: python unit-testing python-unittest


【解决方案1】:

发布的代码是错误的。首先,class myClass(): 应该是 class myClass:if name == "main": 也应该是:

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

除了这些问题之外,这会失败,因为 getName() 引发异常 myExcOne 并且您的测试预计异常 myExcTwo

这是一些有效的代码。请编辑您问题中的代码,以便我们可以轻松地将其剪切并粘贴到 Python 会话中:

import unittest

class myExcOne(Exception): "exception one"

class myExcTwo(Exception): "exception two"

class myClass:
    def getName(self):
        raise myExcTwo

class test_myClass(unittest.TestCase):
    def setUp(self):
        self.myClass = myClass()
    def testgetNameEmpty(self):
        #self.assertRaises(myExcOne,self.myClass.getName)
        self.assertRaises(myExcTwo,self.myClass.getName)

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

【讨论】:

  • 嗨 mhawke,main 在复制和粘贴过程中搞砸了。对于myClass(),继承了原来的类,所以我在做小测试用例时忘记删除()。测试应该是失败的。我试图了解断言失败时该工具的行为方式。对于我原来的帖子,我误解了如果断言失败,该工具应该抛出异常。我已经更新了代码以捕获异常并且什么都不做。即使断言失败,报告说它通过了。布赖恩
【解决方案2】:

顺便说一句,class 语句中类名后面的() 在现代 Python 中是完全正确的——根本不是错误。

关于问题的实质,assertRaises(MyException, foo) 记录了通过调用 foo() 引发的异常,其类型不是 MyException 的子类 --它只捕获MyException 及其子类。由于您的代码引发了一种类型的异常,并且您的测试需要一种不同的不相关类型,然后根据unittest 模块here 的文档,引发的异常将传播,我引用:

如果引发了异常,则测试通过,如果引发另一个异常则为错误,如果未引发异常,则测试失败。

“是一个错误”的意思是“传播另一个异常”。

当您捕捉到在您的 try/except 块中传播的异常时,您会取消错误,并且没有任何东西可供unittest 诊断。如果您的目的是将此错误转变为失败(一个值得商榷的策略...),您的 except 块应该调用 self.fail

【讨论】:

  • 感谢您的帮助!!!直到我发布之后,我才发现我对 unittest 的误解。如果我运行上面的代码,我会收到消息 main.test_myClass) ... ok>。我预计它会失败,但理解它为什么会给出信息。当我在 except 块中添加 self.fail 时,它会引发另一个异常。有什么建议可以让所有测试运行并在最后报告错误吗?我找到了 但我不确定如何(或者如果可以的话)得到结果。
  • 所有测试方法都运行并报告错误 (E) 和故障 (F) [实际上是由特殊异常诊断的] 使用正常的单元测试运行程序 (unittest.main) -- 我'听到 TextTestRunner 对你的行为不同,我感到很惊讶,因为这正是 unittest.main 使用的(通过 unittest.TestProgram 类),检查源...你确实得到了 w/unittest.main 的预期结果,对吗?
  • 如果我取出 try/except 块并取消注释 那么我的调试器正在停止执行。我从命令行运行程序,它运行了所有测试并给出了我期望的结果。这就是我一直在寻找的。但是,如果我运行上面列出的代码,它会告诉我它通过了,即使它应该失败。我不担心这一点,因为从命令行运行单元测试给了我想要的东西。再次感谢您的帮助。
  • 您的调试器显然过于急于过早地捕获将在“上游”处理得很好的异常。检查如何将调试器配置为不这样做!-) 不,您在上面编写代码的方式不应该以任何方式、形状或形式失败,正如我所解释的:您故意通过捕获和忽略来强制它成功例外。
猜你喜欢
  • 2013-07-09
  • 2021-11-22
  • 2011-05-18
  • 2021-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 2012-02-15
相关资源
最近更新 更多