发现后过滤测试

Filter tests after discover

我目前运行我的测试是这样的:

tests = unittest.TestLoader().discover('tests')
unittest.TextTestRunner().run(tests)

现在我想 运行 知道他的名字(比如 test_valid_user)但不知道他的 class 的特定测试。如果有不止一个这样的测试,我想 运行 所有这样的测试。 discover之后有没有办法过滤测试?

或者这个问题可能有其他解决方案(请注意,它不应该从命令行完成)?

有两种方法运行单个测试方法:

命令行:

$ python -m unittest test_module.TestClass.test_method

使用 Python 脚本:

import unittest

class TestMyCode(unittest.TestCase):

    def setUp(self):
        pass

    def test_1(self):
        self.assertTrue(True)

    def test_2(self):
        self.assertTrue(True)

if __name__ == '__main__':
    testSuite = unittest.TestSuite()
    testSuite.addTest(TestMyCode('test_1'))
    runner=unittest.TextTestRunner()
    runner.run(testSuite)

Output:

------------------------------------------------------------

Ran 1 test in 0.000s

OK

另一种更简单的方法是将 py.test-k 选项一起使用,该选项会执行测试名称关键字扫描。它将 运行 名称与关键字表达式匹配的任何测试。

尽管这是使用您不想要的命令行,但请注意您可以使用 subprocess.call 从您的代码中调用命令行以动态传递您想要的任何参数。

例如:假设您有以下测试:

def test_user_gets_saved(self): pass
def test_user_gets_deleted(self): pass
def test_user_can_cancel(self): pass

您可以从 cli:

调用 py.test
$ py.test -k "test_user"

或来自代码:

return_code = subprocess.call('py.test -k "test_user"', shell=True)

您可以使用 unittest.loader.TestLoader.testMethodPrefix 实例变量根据不同于 "test" 的前缀更改测试方法过滤器。

假设您有一个 tests 目录,其中包含这个单元测试之王:

import unittest


class MyTest(unittest.TestCase):
    def test_suite_1(self):
        self.assertFalse("test_suite_1")

    def test_suite_2(self):
        self.assertFalse("test_suite_2")

    def test_other(self):
        self.assertFalse("test_other")

您可以编写自己的 discover 函数来仅发现以 "test_suite_" 开头的测试函数,例如:

import unittest


def run_suite():
    loader = unittest.TestLoader()
    loader.testMethodPrefix = "test_suite_"
    suite = loader.discover("tests")
    result = unittest.TestResult()
    suite.run(result)
    for test, info in result.failures:
        print(info)


if __name__ == '__main__':
    run_suite()

备注discover方法中的参数"tests"是目录路径,可能需要写全路径

因此,您将获得:

Traceback (most recent call last):
  File "/path/to/tests/test_my_module.py", line 8, in test_suite_1
    self.assertFalse("test_suite_1")
AssertionError: 'test_suite_1' is not false

Traceback (most recent call last):
  File "/path/to/tests/test_my_module.py", line 11, in test_suite_2
    self.assertFalse("test_suite_2")
AssertionError: 'test_suite_2' is not false