使用 pytest 控制哪些测试 运行

Controlling which tests run using pytest

我正在考虑将一些 unittest.TestCase 测试转换为 Pytest 测试以利用 Pytest 的固定装置。然而,unittest 的一项功能是我无法轻易在 Pytest 中找到与之等效的功能,那就是能够创建测试套件并 运行 它们。我目前经常做这样的事情:

import unittest

class TestSomething(unittest.TestCase):
    def test_1(self):
        self.assertEqual("hello".upper(), "HELLO")

    def test_2(self):
        self.assertEqual(1+1, 2)

if __name__ == "__main__":
    suite = unittest.TestSuite()
    # suite.addTest(TestSomething('test_1'))
    suite.addTest(TestSomething('test_2'))
    runner = unittest.TextTestRunner()
    runner.run(suite)

通过注释掉 addTest 行,我可以轻松地 select 测试 运行。我将如何使用 Pytest 做类似的事情?

您可以将 -k 参数用于 运行 特定测试。例如

# put this in test.py
import unittest

class TestSomething(unittest.TestCase):
    def test_1(self):
        self.assertEqual("hello".upper(), "HELLO")

    def test_2(self):
        self.assertEqual(1+1, 2)

运行 class TestSomething 中的所有测试都可以这样完成:

py.test test.py -k TestSomething

运行 仅 test_2:

py.test test.py -k "TestSomething and test_2"

documentation

中有更多示例

除了使用 -k 过滤器外,您还可以命名特定测试 类 或您想要 运行、

的案例
py.test test.py::TestSomething::test_2

运行 只是 test_2

另一种方法是使用特殊的测试名称。这些可以在 pytest.ini 文件中配置。

# content of pytest.ini
# can also be defined in tox.ini or setup.cfg file, although the section
# name in setup.cfg files should be "tool:pytest"
[pytest]
python_files=check_*.py
python_classes=Check
python_functions=*_check

另一种方法是在 conftest.py 中采取行动。在此示例中,使用了 collect_ignore 配置变量。它是要忽略的测试路径列表。在此示例中,test_somthing.py 始终被忽略以进行收集。如果我们使用 python 3.

进行测试,test_other_module_py2.py 将被忽略
# content of conftest.py
import sys

collect_ignore = ["test_something/test_something.py"]
if sys.version_info[0] > 2:
    collect_ignore.append("test_other/test_other_module_py2.py")

从 pytest 2.6 开始,也可以像这样从测试注册中省略 类:

# Will not be discovered as a test
class TestClass:
    __test__ = False

这些示例大致取自 pytest 章节 Changing standard (Python) test discovery

的文档

基于 mbatchkarov 的回答,由于我的测试名称可能会变得很长,我希望仍然能够 select 通过评论行内和行外并点击 "Cntrl+B" 在 Sublime 中(或 "Cntrl+R" 使用 Atom Runner)。一种方法如下:

import unittest
import pytest

class TestSomething(unittest.TestCase):
    def test_1(self):
        self.assertEqual("hello".upper(), "HELLO")

    def test_2(self):
        self.assertEqual(1+1, 2)

if __name__ == "__main__":
    tests_to_run = []
#   tests_to_run.append('TestSomething and test_1')
    tests_to_run.append('TestSomething and test_2')
    tests_to_run = " or ".join(tests_to_run)
    args = [__file__, '-k', tests_to_run]
    pytest.main(args)

这背后的想法是,因为 Pytest 接受一个字符串表达式来匹配测试(而不仅仅是测试列表),所以必须生成一个仅匹配一个测试的表达式列表,并使用 [=11= 连接它们].

认为最好的方法是使用自定义 pytest 标记。 你应该标记特定的测试(你想要 运行) @pytest.mark.mymarkername

而 运行 仅使用命令使用自定义标记进行测试: py.test -v -m mymarkername

您可以在此处找到有关标记的更多信息: http://doc.pytest.org/en/latest/example/markers.html