除非明确要求,否则禁用某些测试的自动测试执行

Disable automatic test execution for some tests unless those are explicitly requested

我有一些非常慢的测试和许多短的单元测试。我希望能够 运行 仅使用简单的 nosetests 命令进行短单元测试,如果我决定是时候进行 运行 慢速测试,以便能够显式调用它们。

我希望能够做的事情:

我尝试了什么:

我尝试使用 nose.plugins.attrib:

from nose.plugins.attrib import attr
import time

@attr('slow')
def test_slow_one():
    time.sleep(5)

def test_unittest():
    assert True

但它实际上与我想要完成的几乎相反 - 我必须指定额外的命令行参数以 而不是 运行 慢速测试。命令是:

运行 单元测试但不是慢测试

$ nosetests -v -a '!slow'
test_a.test_unittest ... ok
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK

明确要求慢速测试:

$ nosetests -v -a 'slow'
test_a.test_slow_one ... ok
----------------------------------------------------------------------
Ran 1 test in 5.005s
OK

更糟糕的是,当有人 运行 只是

$ nosetests -v
test_a.test_slow_one ... ok
test_a.test_unittest ... ok
----------------------------------------------------------------------
Ran 2 tests in 5.007s
OK

所有测试 包括慢测试都将是 运行.

问题:

有没有办法禁用一些测试,这样它们就不会被普通 nosetests 命令调用,但可以 运行 使用一些额外的命令行参数?

当前 "solution":

我只是将所有慢速测试移到单独的文件中,并将文件命名为 check_*.py 而不是 test_*.py,因此 nosetests 不会拾取它们。当我想要 运行 慢速测试时,我只指定 check_*.py 文件的整个路径,例如:

$ nosetests test/check_foo.py test/check_bar.py [...]

这不是很优雅。

您可以很容易地使用 unittest.skipUnless() 达到这种效果。

跳过单个测试

只需 decorate 您想要有条件地跳过的测试用例方法

@unittest.skipUnless(condition, reason)

例如,您可以检查您根本没有在自动化 CI 环境中设置的 环境变量 SLOW_TESTS,但是如果当您想 运行 在本地进行慢速测试时:

import os
import time
import unittest


SLOW_TESTS = os.environ.get('SLOW_TESTS', False)


    class TestFoo(unittest.TestCase):

        def test_upper(self):
            self.assertEqual('foo'.upper(), 'FOO')

        @unittest.skipUnless(SLOW_TESTS, "slow test")
        def test_something_slow(self):
            time.sleep(5)
            self.assertTrue(True)

常规 运行 的输出:

$ nosetests -v
test_something_slow (test_foo.TestFoo) ... SKIP: slow test
test_upper (test_foo.TestFoo) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK (SKIP=1)

设置环境变量时的输出:

$ SLOW_TESTS=1 nosetests -v
test_something_slow (test_foo.TestFoo) ... ok
test_upper (test_foo.TestFoo) ... ok

----------------------------------------------------------------------
Ran 2 tests in 5.003s

OK

(请注意,Nose 测试运行 仍然显示 Ran 2 tests,即使它跳过了一个。跳过的测试在最后用 (SKIP=n) 表示并在非详细模式下使用 SKIPS 的测试结果。

当然,您可以通过使用 skipIf() 使用您在 CI 设置中设置的 FAST_TESTS 等环境变量来反转行为。

跳过整个测试用例

如果你想跳过 TestCase 中的 all 测试,你知道它很慢或有一些繁重的设置,显式调用 TestCase.skipTest() 可能更方便(如果您需要更细粒度的控制,您也可以从单个测试中做到这一点):

class TestFoo(unittest.TestCase):

    def setUp(self):
        if not SLOW_TESTS:
            self.skipTest("slow test")
        # some expensive setup

有关跳过测试的更多详细信息,请参阅 Skipping tests and expected failures