如何为模块内所有测试定义初始化和清理方法

4 投票
2 回答
1973 浏览
提问于 2025-04-18 06:19

我正在使用nosetest作为我的测试框架,所有的测试都是函数。
这些测试函数并不在一个类里面。

我不想给每个函数都加上设置的装饰器,而是想定义一个设置和清理的函数,这样只需要写一次,就能在每个测试之前和之后运行。

有没有人知道一个优雅的方法来做到这一点?

2 个回答

1

这可能不是最优雅的做法,但能完成任务。首先,在你定义测试的包里,创建一个 decorators.py 文件,写入以下内容:

def setup_func():
    "set up test fixtures"

def teardown_func():
    "tear down test fixtures"

然后,在一个 tests.py 文件中,导入以下内容:

from decorators import setup_func, teardown_func
from inspect import getmodule
from nose.tools import with_setup
from types import FunctionType

接下来,你可以像往常一样定义所有的测试。当你完成后,在文件的最底部写入:

for k, v in globals().items():
    if isinstance(v, FunctionType) and getmodule(v).__name__ == __name__:
        v = with_setup(setup_func, teardown_func)(v)

这样会给 tests.py 中定义的每个函数(而不是导入的函数)添加设置和清理的过程。

不过要注意,即使是那些不符合 nose 测试标准的函数也会被装饰。所以一些辅助和工具函数也会被装饰,和你其他的函数一样。在绝大多数情况下,这样做是比较安全的。然而,如果你担心这会影响到你的实际测试,可以把它们定义在另一个模块里,然后导入过来。

补充说明:这一切都能正常工作,并且符合你所需的非常特定的解决方案。没有类,每个函数都有装饰,也不需要手动添加 @with_setup 装饰等等。不过,我强烈建议你把测试函数移动到一个 TestCase 中。这很简单,便于移植,而且是将具有相同设置和清理的测试分组的标准方式。

2

这是unittest的默认行为:

test.py:
import unittest

class TestFixture(unittest.TestCase):
    def setUp(self):
        print "setting up"

    def tearDown(self):
        print "tearing down"

    def test_sample1(self):
        print "test1"

    def test_sample2(self):
        print "test2"

它的作用是:

    $ python -m unittest test
    setting up
    test1
    tearing down
    .setting up
    test2
    tearing down
    .
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s

    OK

撰写回答