running a test suite (an arbitrary collection of tests) with py.test
我正在使用py.test构建功能测试框架,因此我需要能够指定要运行的确切测试。我了解动态测试集合的优点,但我希望能够先运行测试环境运行状况检查,然后再运行回归测试;该分类并不排除这些集中的测试可用于其他目的。
测试套件将与Jenkins构建项目联系在一起。我正在使用osx,python 2.7.3,py.test 2.3.4。
所以我有一个如下的测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # sample_unittest.py import unittest, pytest class TestClass(unittest.TestCase): def setUp(self): self.testdata = ['apple', 'pear', 'berry'] def test_first(self): assert 'apple' in self.testdata def test_second(self): assert 'pear' in self.testdata def tearDown(self): self.testdata = [] def suite(): suite = unittest.TestSuite() suite.addTest(TestClass('test_first')) return suite if __name__ == '__main__': unittest.TextTestRunner(verbosity=2).run(suite()) |
我有一个像这样的测试套件:
1 2 3 4 5 6 7 8 9 10 11 12 13 | # suite_regression.py import unittest, pytest import functionaltests.sample_unittest as sample_unittest # set up the imported tests suite_sample_unittest = sample_unittest.suite() # create this test suite suite = unittest.TestSuite() suite.addTest(suite_sample_unittest) # run the suite unittest.TextTestRunner(verbosity=2).run(suite) |
如果我从命令行对套件运行以下命令,则test_first会运行(但我没有得到py.test提供的其他信息):
python functionaltests/suite_regression.py -v
如果对套件运行以下命令,则会收集0个测试:
py.test functionaltests/suite_regression.py
如果我针对测试用例运行以下命令,请运行test_first和test_second:
py.test functionaltests/sample_unittest.py -v
我看不到用关键字py.test如何帮助将测试组织到套件中。将测试用例放置在文件夹结构中并使用文件夹选项运行py.test不会让我按功能区域组织测试。
所以我的问题是:
编辑:
因此,我尝试了py.test标记,该标记使我可以使用任意标签标记测试功能和测试方法,然后在运行时过滤该标签。
1 2 3 4 5 6 | # conftest.py import pytest # set up custom markers regression = pytest.mark.NAME health = pytest.mark.NAME |
和我更新的测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # sample_unittest.py import unittest, pytest class TestClass(unittest.TestCase): def setUp(self): self.testdata = ['apple', 'pear', 'berry'] @pytest.mark.healthcheck @pytest.mark.regression def test_first(self): assert 'apple' in self.testdata @pytest.mark.regression def test_second(self): assert 'pear' in self.testdata def tearDown(self): self.testdata = [] def suite(): suite = unittest.TestSuite() suite.addTest(TestClass('test_first')) return suite if __name__ == '__main__': unittest.TextTestRunner(verbosity=2).run(suite()) |
因此,运行以下命令将收集并运行test_first:
py.test functionaltests/sample_unittest.py -v -m healthcheck
并收集并运行test_first和test_second:
py.test functionaltests/sample_unittest.py -v -m regression
回到我的问题:标记是部分解决方案,但是我仍然没有办法控制收集的标记测试的执行。
我想现在有点晚了,但是我在这里完成了一个带有文档的交互式选择插件:
https://github.com/tgoodlet/pytest-interactive
我实际上使用了上面提到的钩子Holger。
它允许您在收集阶段之后使用IPython选择测试的选择。如果您要这样做,则可以使用切片,下标或制表符完成命令来订购测试。请注意,它是一个交互式工具,旨在在开发期间使用,而对于自动回归运行而言则不是很多。
对于使用标记的持久排序,我使用了pytest-ordering,它实际上非常有用,尤其是当您在较长的回归套件中具有基线前提测试时。
在这种情况下,无需使用标记:在py.test测试类上设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # sequential.py import pytest @pytest.mark.incremental class TestSequential: def test_first(self): print('first') def test_second(self): print('second') def test_third(self): print('third') |
现在运行
1 | pytest -s -v sequential.py |
产生以下输出:
1 2 3 4 5 6 7 8 9 10 | =========== test session starts =========== collected 3 items sequential.py::TestSequential::test_first first PASSED sequential.py::TestSequential::test_second second PASSED sequential.py::TestSequential::test_third third PASSED =========== 3 passed in 0.01 seconds =========== |
当前没有直接的方法来控制测试执行的顺序。 FWIW,有一个插件挂钩