python unittest assertRaises 在 assertRaises 失败时抛出异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1230498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:44:34  来源:igfitidea点击:

python unittest assertRaises throws exception when assertRaises fails

pythonunit-testingpython-unittest

提问by

I've got code where assertRaises throws an exception when assertRaises fails. I thought that if assertRaises fails then the test would fail and I'd get a report at the end that says the test failed. I wasn't expecting the exception to be thrown. Below is my code. I'm I doing something wrong? I'm using Python 2.6.2.

我有代码,当 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)

回答by mhawke

The code as posted is wrong. For a start, class myClass():shoudl be class myClass:. Also if name == "main":should be:

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

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

Apart from these problems, this fails because getName()is raising exception myExcOneand your test expects exception myExcTwo.

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

Here is some code that works. Please edit the code in your question so that it is easy for us to cut and paste it into a Python session:

这是一些有效的代码。请编辑您问题中的代码,以便我们可以轻松地将其剪切并粘贴到 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()

回答by Alex Martelli

Starting with an aside, the ()after the classname in a classstatement is perfectly correct in modern Python -- not an error at all.

与旁边,开始()在类名之后class的语句是现代的Python完全正确的-不是错误的。

On the meat of the issue, assertRaises(MyException, foo)isdocumented to propagate exceptions raised by calling foo()whose type is NOT a subclass of MyException-- it only catches MyExceptionand subclasses thereof. As your code raises an exception of one type and your test expects one of a different unrelated type, the raised exception will then propagate, as per the docs of the unittestmodule, here, and I quote:

在问题的核心上,assertRaises(MyException, foo)记录为传播通过调用foo()其类型不是的子类而引发的异常MyException——它只捕获MyException及其子类。当您的代码引发一种类型的异常并且您的测试期望一种不同的不相关类型时,引发的异常将传播,根据unittest模块的文档,here,我引用:

The test passes if exceptionis raised, is an error if another exception is raised, or fails if no exception is raised.

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

And "is an error" means "propagates the other exception".

“是一个错误”意味着“传播另一个异常”。

As you catch the exception propagating in your try/except block, you nullify the error, and there's nothing left for unittestto diagnose. If your purpose is to turn this error into a failure (a debatable strategy...), your exceptblock should call self.fail.

当您捕获在 try/except 块中传播的异常时,您消除了错误,并且没有什么unittest可诊断的了。如果您的目的是将此错误转化为失败(一个有争议的策略......),您的except块应该调用self.fail.