我正在扩展python 2.7 unittest
框架来做一些功能测试。我想要做的一件事就是停止在测试中运行所有测试,并在方法内部停止。有时候如果一个测试失败了,那么这个程序就会被破坏,不再用于继续测试,所以我想停止运行测试。如何使用unittest停止测试或setUp中的所有测试?
我注意到TestResult有一个shouldStop
属性和一个stop()
方法,但我不确定如何访问测试的内部。
有没有人有任何想法?有没有更好的办法?
我正在扩展python 2.7 unittest
框架来做一些功能测试。我想要做的一件事就是停止在测试中运行所有测试,并在方法内部停止。有时候如果一个测试失败了,那么这个程序就会被破坏,不再用于继续测试,所以我想停止运行测试。如何使用unittest停止测试或setUp中的所有测试?
我注意到TestResult有一个shouldStop
属性和一个stop()
方法,但我不确定如何访问测试的内部。
有没有人有任何想法?有没有更好的办法?
下面是另一个答案,我想出了一段时间后:
首先,我添加了一个新的异常:
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())
and last I overrde run
function to include this right below the testMethod()
call:
except StopTests:
result.addFailure(self, sys.exc_info())
result.stop()
我更喜欢这样,因为现在任何测试都可以停止所有测试,并且没有特定于cpython的代码。
StopTests在哪里引发? – 2017-03-21 09:17:02
目前,您只能在套件级别停止测试。一旦你在TestCase
中,在遍历测试时不会使用TestResult
的stop()
方法。
与您的问题有些相关,如果您使用的是Python 2.7,那么在调用您的测试python -m unittest
时可以使用-f/--failfast
标志。这将在第一次失败时停止测试。
谢谢。我看到了failfast选项,但我并不总是想在第一个错误上失败,只是在选定的位置。我想我应该编辑我的问题,提到我使用Python 2.7。 – user197674 2010-09-27 20:17:10
我看着TestCase
类,并决定将其继承。该课程仅覆盖run()
。我复制的方法,并在原班开始于行318添加了这个:
# this is CPython specific. Jython and IronPython may do this differently
if testMethod.func_code.co_argcount == 2:
testMethod(result)
else:
testMethod()
它有没有一些具体的CPython代码告诉如果测试方法可以接受另一个参数,而且因为我到处使用的CPython ,这对我来说不是问题。
如果你有兴趣,这里是一个简单的例子,你怎么能自己做决定有关干净退出测试套件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失败后停止。
Sidenote2:py.test
对传统unittest.TestCase
风格的运行测试的支持有限。
谢谢。我不知道这个测试框架。我会看看它。 – user197674 2010-10-04 18:42:26
当前版本的Py.Test:导入pytest,然后你可以做pytest.exit(“你的消息”) – RvdK 2014-04-10 08:24:18
这也适用于在conftest.py文件中声明的pytest夹具,scope ='session',autouse =真正。这将在项目的每个测试之前运行。从这里调用pytest.exit可以在任何测试运行之前中止整个测试运行。我用它来中止测试,如果他们正在使用prod配置(实际上是任何非测试配置)运行 – 2017-03-08 20:06:59
在unittest.TestSuite
测试回路中,有在开始一个break
条件:
class TestSuite(BaseTestSuite):
def run(self, result, debug=False):
topLevel = False
if getattr(result, '_testRunEntered', False) is False:
result._testRunEntered = topLevel = True
for test in self:
if result.shouldStop:
break
所以我用一个自定义的测试套件是这样的:
class CustomTestSuite(unittest.TestSuite):
""" This variant registers the test result object with all ScriptedTests,
so that a failed Loign test can abort the test suite by setting result.shouldStop
to True
"""
def run(self, result, debug=False):
for test in self._tests:
test.result = result
return super(CustomTestSuite, self).run(result, debug)
使用自定义的测试结果类似这样:
class CustomTestResult(TextTestResult):
def __init__(self, stream, descriptions, verbosity):
super(CustomTestResult, self).__init__(stream, descriptions, verbosity)
self.verbosity = verbosity
self.shouldStop = False
和我的测试类是像:
class ScriptedTest(unittest.TestCase):
def __init__(self, environment, test_cfg, module, test):
super(ScriptedTest, self).__init__()
self.result = None
在某些条件下,我中止测试套件;例如,测试套件与登录开始,如果失败了,我没有尝试休息:
try:
test_case.execute_script(test_command_list)
except AssertionError as e:
if test_case.module == 'session' and test_case.test == 'Login':
test_case.result.shouldStop = True
raise TestFatal('Login failed, aborting test.')
else:
raise sys.exc_info()
然后我使用测试套件通过以下方式:
suite = CustomTestSuite()
self.add_tests(suite)
result = unittest.TextTestRunner(verbosity=self.environment.verbosity, stream=UnitTestLoggerStream(self.logger),
resultclass=CustomTestResult).run(suite)
我不确定是否有更好的方法来做到这一点,但它对我的测试表现正确。
尽管目前为止您无法获得目前运行的测试的常规测试报告,但在TestCase
方法中停止测试的一种非常简单的方法就是在该方法内部提升KeyboardInterrupt
。
通过查看012y中的CPython代码here,您可以看到KeyboardInterrupt
只允许在unittest
的测试运行器中出现泡沫。
如果使用prod设置配置了测试下的应用程序,我会在运行任何测试之前使用它来中止测试运行。 (实际上,与任何非测试设置。) – 2017-03-08 20:04:24