如何在unittest中在测试或setUp内部停止所有测试?

31 投票
8 回答
24700 浏览
提问于 2025-04-16 04:39

我正在扩展 Python 2.7 的 unittest 框架,目的是进行一些功能测试。我想做的一件事是,在测试中和 setUpClass() 方法里停止所有测试的运行。有时候,如果一个测试失败了,程序可能已经坏得没法再测试下去了,所以我想停止后续的测试。

我注意到 TestResult 有一个 shouldStop 属性和一个 stop() 方法,但我不太确定怎么在测试中访问到这些内容。

有没有人有什么想法?有没有更好的方法?

8 个回答

4

目前,你只能在测试套件的层面上停止测试。一旦进入了一个 TestCase,在遍历测试时,TestResultstop() 方法就不会被使用。

和你的问题有点关系,如果你使用的是 Python 2.7,你可以在用 python -m unittest 运行测试时,加上 -f/--failfast 这个选项。这样的话,测试会在第一次失败的时候就停止。

可以查看 25.3.2.1. failfast, catch and buffer 命令行选项 来了解更多信息。

你也可以考虑使用 Nose 来运行你的测试,并使用 -x, --stop 选项 来提前停止测试。

30

如果你感兴趣,这里有一个简单的例子,教你如何用 py.test 自己决定是否要干净利落地退出测试套件:

# content of test_module.py
import pytest
counter = 0
def setup_function(func):
    global counter
    counter += 1
    if counter >=3:
        pytest.exit("decided to stop the test run")

def test_one():
    pass
def test_two():
    pass
def test_three():
    pass

运行这个代码后,你会得到:

$ pytest test_module.py 
============== test session starts =================
platform linux2 -- Python 2.6.5 -- pytest-1.4.0a1
test path 1: test_module.py

test_module.py ..

!!!! Exit: decided to stop the test run !!!!!!!!!!!!
============= 2 passed in 0.08 seconds =============

你也可以把 py.test.exit() 这个调用放在一个测试里面,或者放到一个特定项目的插件里。

顺便提一下:py.test 自带支持 py.test --maxfail=NUM 这个命令,可以在失败达到 NUM 次后自动停止测试。

再补充一下:py.test 对于传统的 unittest.TestCase 风格的测试支持有限。

6

这是我经过一段时间后想到的另一个答案:

首先,我添加了一个新的异常:

class StopTests(Exception):
"""
Raise this exception in a test to stop the test run.

"""
    pass

然后我在我的子测试类中添加了一个新的 assert 语句:

def assertStopTestsIfFalse(self, statement, reason=''):
    try:
        assert statement            
    except AssertionError:
        result.addFailure(self, sys.exc_info())

最后,我重写了 run 函数,把这个代码放在 testMethod() 调用的下面:

except StopTests:
    result.addFailure(self, sys.exc_info())
    result.stop()

我更喜欢这样,因为现在任何测试都可以停止所有的测试,而且没有特定于 cpython 的代码。

撰写回答