如何在unittest中在测试或setUp内部停止所有测试?
我正在扩展 Python 2.7 的 unittest
框架,目的是进行一些功能测试。我想做的一件事是,在测试中和 setUpClass()
方法里停止所有测试的运行。有时候,如果一个测试失败了,程序可能已经坏得没法再测试下去了,所以我想停止后续的测试。
我注意到 TestResult 有一个 shouldStop
属性和一个 stop()
方法,但我不太确定怎么在测试中访问到这些内容。
有没有人有什么想法?有没有更好的方法?
8 个回答
目前,你只能在测试套件的层面上停止测试。一旦进入了一个 TestCase
,在遍历测试时,TestResult
的 stop()
方法就不会被使用。
和你的问题有点关系,如果你使用的是 Python 2.7,你可以在用 python -m unittest
运行测试时,加上 -f/--failfast
这个选项。这样的话,测试会在第一次失败的时候就停止。
可以查看 25.3.2.1. failfast, catch and buffer 命令行选项 来了解更多信息。
如果你感兴趣,这里有一个简单的例子,教你如何用 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
风格的测试支持有限。
这是我经过一段时间后想到的另一个答案:
首先,我添加了一个新的异常:
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 的代码。