assertRaises只捕获基本异常

时间:2010-01-06 12:59:59

标签: python unit-testing assertraises

使用unittest.assertRaises时遇到了一个奇怪的问题。执行下面的代码时,我得到以下输出:

E
======================================================================
ERROR: testAssertRaises (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\home\python_test\src\derived.py", line 29, in testAssertRaises
    self.assertRaises(MyError, self.raiser.raiseMyError)
  File "C:\Programme\Python26\lib\unittest.py", line 336, in failUnlessRaises
    callableObj(*args, **kwargs)
  File "C:\home\python_test\src\derived.py", line 15, in raiseMyError
    raise MyError("My message")
MyError: 'My message'

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

FAILED (errors=1)

引发了正确的异常,但测试失败了!如果我抓住BaseError测试成功了。

不知怎的,这似乎是unittest无法看到MyError异常类的范围问题。有人可以解释一下吗?有一些解决方法吗?

我正在测试以下Python代码,这是一个通过类名动态构造对象的实现。

这是基本模块“bases.py”:

class BaseClass(object):

    @staticmethod
    def get(className):
        module = __import__("derived", globals(), locals(), [className])
        theClass = getattr(module, className)
        return theClass()


class BaseError(Exception):

    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return repr(self.msg)

这是要测试的模块,“derived.py”:

import unittest

from bases import BaseError
from bases import BaseClass


class MyErrorRaiser(BaseClass):    

    def raiseMyError(self):
        raise MyError("My message")


class MyError(BaseError):
    '''
    '''


class Test(unittest.TestCase):

    def setUp(self):
        self.raiser = BaseClass.get("MyErrorRaiser")

    def testAssertRaises(self):
        self.assertRaises(MyError, self.raiser.raiseMyError)


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

3 个答案:

答案 0 :(得分:2)

作为mentioned,问题是模块 __ main __ 派生的不是同一个;这个答案是关于你如何解决这个问题的。

不要混合模块代码和脚本代码。开始将if __name__ == "__main__"代码视为 hack 。 (它有时候仍然非常方便,我经常使用它进行调试等,但视为一个黑客,所以你总是会轻微地思考它。)然后运行的新脚本一切都很简单(从不导入):

#!/usr/bin/env python
import derived
import sys
sys.exit(derived.main(sys.argv[1:]))

或根据个人喜好存在各种差异。只需确保添加derived.main即可执行您想要的操作。

我还看到另一个不太常见的黑客,在derived.py的顶部

import sys
if __name__ == "__main__":
  import derived # import the same module under its "correct" name
  sys.exit(derived.main(sys.argv[1:]))

虽然在解析相同的代码两次时浪费了,但这在交换中是独立的。

答案 1 :(得分:1)

运行derived.py时,它将作为__main__模块运行(因为您直接运行它而不是导入它)。稍后显式导入时,会创建另一个模块副本,这次是名称derived。因此__main__.MyErrorderived.MyError不同,并且未捕获异常。

答案 2 :(得分:0)

问题可能是你的BaseClass.get()方法正在返回另一个类。顺便说一下,这种方法本身很可怕,我想知道你为什么要这样做。