我伸python2.7 unittest 框架做了一些功能测试。有一件事我想做的是停止所有试验运行的内部测试和内部的一个 setUpClass() 法。有时,如果一个测试失败,程序是破它不再是任何使用保留检测,所以,我想要停止测试运行。

我注意到,一TestResult有一个 shouldStop 属性,一种 stop() 方法,但是我不知道如何获得这里的一个测试。

没有任何人有任何想法?是否有一个更好的办法?

有帮助吗?

解决方案 2

下面是我一段时间后,想出了另一个答案:

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

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的特定代码。

其他提示

如果你有兴趣,这里是一个简单的例子,你怎么能做出具有的 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风格运行测试只有有限的支持

目前,只能停留在浴室的水平测试。一旦你在一个TestCase,通过迭代测试时,不用于stop()TestResult方法。

有点关系到你的问题,如果你正在使用python 2.7,你可以调用带有-f/--failfast测试时所使用的python -m unittest标志。这将在第一故障停止测试。

请参阅 25.3.2.1。故障快速转移,捕捉和缓冲器命令行选项

您也可以考虑使用鼻子来运行测试,并使用-x, --stop 标志提前停止测试。

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类和决定子类它。该类只是覆盖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的无处不在,这不是我的问题。

虽然你不会获得通常的测试报告的运行测试迄今为止,一个非常简单的方式停止运行测试从 TestCase 方法是简单地提高 KeyboardInterrupt 里面的方法。

你可以看到的只有 KeyboardInterrupt 允许泡在里面 unittest's测试运看CPython的代码 在这里, 内部 testPartExecutor().

使用:

if condition: 
   return 'pass'
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top