3

我有一个使用套接字进行测试的 TestCase。即使在出现错误的情况下,您也应该始终关闭套接字,因此我创建了一个抽象套接字的上下文管理器类。

测试夹具如下所示,其中MyClassToTest要测试的实际类在内部使用套接字设备。

with SocketContextManager() as device:
    foo = MyClassToTest(device)
    # make tests with foo

我想避免在每个测试夹具中重复这两行,但始终放在setUp. 但是我该怎么做呢?以下代码

def setUp(self):
    with SocketContextManager() as device:
        self.foo = MyClassToTest(device)

不起作用,因为设备将在结束时关闭setUp。有没有办法像这样处理上下文管理器的实例化,还是我必须在每个测试夹具中重复它?

4

2 回答 2

2

根据拆解的文档

即使测试方法引发异常,也会调用此方法

因此,您可以在 中打开套接字setUp,然后在 中将其关闭tearDown。即使您的测试用例引发异常,套接字仍将关闭。

于 2012-12-14T08:15:04.557 回答
1

这是一个非常有趣的问题。正如 BrenBarn 指出的那样,unittest 框架不支持做你想做的事,但在我看来,没有什么特别的原因不能让你适应它。setUp/tearDown配对是其他没有生成器的语言的遗留物。

下面的代码定义了一个新的 'ContextTest' 类,它将 setUp 和 tearDown 方法合并到一个生成器中,该生成器既可以构建也可以销毁测试的上下文。您可以将您的with语句context()与任何其他样板一起放入方法中。

#!/usr/bin/python3.3
import unittest

class ContextTest(unittest.TestCase):
    """A unit test where setUp/tearDown are amalgamated into a
    single generator"""
    def context(self):
        """Put both setUp and tearDown code in this generator method
        with a single `yield` between"""
        yield

    def setUp(self):
        self.__context = self.context()
        next(self.__context)
    def tearDown(self):
        for _ in self.__context:
            raise RuntimeError("context method should only yield once")

from contextlib import closing
from urllib.request import urlopen

class MyTest(ContextTest):
    def context(self):
        with closing(urlopen('http://www.python.org')) as self.page:
            yield

    def testFoo(self):
        self.assertIsNotNone(self.page)

if __name__=='__main__':
    unittest.main()
于 2012-12-14T08:58:08.517 回答