每个测试方法都有不同的设置和拆除

1 投票
1 回答
1179 浏览
提问于 2025-04-18 16:46

我正在测试一个类,里面有很多测试方法。不过,每个方法的上下文都是独特的。于是我写了如下代码:

class TestSomeClass(unittest.TestCase):
    def test_a():
        with a_context() as c:
            pass

    def test_b():
        with b_context() as c:
            pass

    def test_c():
        with c_context() as c:
            pass

但是,这些上下文管理器和测试用例没有直接关系,而且会生成临时文件。为了避免在测试失败时污染文件系统,我想在设置和清理的过程中使用这些上下文管理器。

我查过nose的with_setup,但文档上说这个只适用于函数,而不适用于方法。另一种方法是把测试方法移动到不同的类中,每个类都有自己的设置和清理函数。请问有什么好的方法来实现这个呢?

1 个回答

1

首先,我不太确定你遇到的问题为什么会出现。我写了一些测试代码,结果显示在unittest.main()这个执行环境下,exit代码总是会被调用。(注意,我没有测试nose,所以可能这就是我无法复现你问题的原因。)也许你的上下文管理器有问题?

这是我的测试代码:

import unittest
import contextlib
import sys

@contextlib.contextmanager
def context_mgr():
    print "setting up context"
    try:
        yield
    finally:
        print "tearing down context"

class TestSomeClass(unittest.TestCase):
    def test_normal(self):
        with context_mgr() as c:
            print "normal task"

    def test_raise(self):
        with context_mgr() as c:
            print "raise task"
            raise RuntimeError

    def test_exit(self):
        with context_mgr() as c:
            print "exit task"
            sys.exit(1)

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

通过运行命令 $ python test_test.py,我看到所有三个测试都显示了 tearing down context

无论如何,回答你的问题,如果你想要每个测试都有单独的准备和清理步骤,那么你需要把每个测试放在自己的类里。你可以设置一个父类来帮你完成大部分工作,这样就不会有太多额外的代码:

class TestClassParent(unittest.TestCase):
    context_guard = context_mgr()
    def setUp(self):
        #do common setup tasks here
        self.c = self.context_guard.__enter__()
    def tearDown(self):
        #do common teardown tasks here
        self.context_guard.__exit__(None,None,None)

class TestA(TestClassParent):
    context_guard = context_mgr('A')
    def test_normal(self):
        print "task A"

class TestB(TestClassParent):
    context_guard = context_mgr('B')
    def test_normal(self):
        print "task B"

这会产生以下输出:

$ python test_test.py 
setting up context: A
task A
tearing down context: A
.setting up context: B
task B
tearing down context: B
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

撰写回答