0

我在使用时遇到了一个奇怪的问题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()
4

3 回答 3

2

如前所述,问题是模块__main__derived不是一回事;这个答案是关于你如何解决这个问题的。

不要混合模块代码和脚本代码。开始将if __name__ == "__main__"代码视为hack。(有时它仍然非常方便,我经常将它用于调试等,但其视为一种 hack,因此您在编写它时总是会受到轻微的心理推动。)然后运行所有内容的新脚本将很简单(而且永远不会进口):

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

或者根据个人喜好有各种差异。只要确保你添加了derived.main 来做你想做的事。

我还在 derived.py 的顶部看到了另一种不太常见的 hack :

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

虽然两次解析相同的代码很浪费,但作为交换,这是自包含的。

于 2010-01-06T17:36:31.087 回答
1

当您运行derived.py 时,它作为__main__模块运行(因为您直接运行它而不是导入它)。当您稍后显式导入它时,会创建该模块的另一个副本,这次名为derived. 所以__main__.MyError与 不一样derived.MyError,并且没有捕获到异常。

于 2010-01-06T13:13:48.897 回答
0

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

于 2010-01-06T13:11:42.167 回答