pytest:重构重复的测试用例

pytest: refactor the repeated testcases

我有如下测试用例:

class TestSomething():
    def test_a(self):
        ...
    def test_b(self):
        ...

它运作良好。但现在我必须更改一些环境设置,重新启动机器使其生效,然后重新测试这些案例。

我能想到的是:

class TestSomething():
    def test_a(self):
        ...
    def test_b(self):
        ...
    # change the env var on the target machine and reboot it
    def test_change_env_and_reboot(self):
        some_env_var = get_env_var()
        if not some_env_var:
            set_env_var()
            reboot()
    def test_a1(self):
        self.test_a()
    def test_b1(self):
        self.test_b()

看起来不太好。有没有更好的方法可以达到同样的目的,而不改变原来已有的测试用例?

更新: 目的是检测some_env_var,如果不是True,设置它并重启机器。之后,重新运行test_atest_b。另一方面,如果 some_env_var 已经设置,则不要重新 运行 这些测试用例。

您可以从您的第一个测试 class 派生并添加一个设置方法(我使用 setup_class 调用一次,如果需要,您可以使用 setup_method,调用每次测试前)。如果您 运行 使用此文件进行 pytest:

import os

class TestSomething:
    def test_a(self):
        pass

    def test_b(self):
        pass


class TestSomethingElse(TestSomething):
    @classmethod
    def setup_class(cls):
        if os.getenv('VAR') == '1':
            pytest.skip("Test not needed")
        else:
            print('Changing configuration...')

你得到:

collecting ... collected 4 items

test_setup.py::TestSomething::test_a PASSED                              [ 25%]
test_setup.py::TestSomething::test_b PASSED                              [ 50%]
test_setup.py::TestSomethingElse::test_a Changing configuration...
PASSED                          [ 75%]
test_setup.py::TestSomethingElse::test_b PASSED                          [100%]

========================== 4 passed in 0.07 seconds ===========================

如您所见,在执行更改后的设置后,每个测试都会再次 运行。

如果不需要测试(这里通过环境变量的值来检测),可以在setup中直接跳过。在这种情况下,您的输出将是:

collecting ... collected 4 items

test_setup.py::TestSomething::test_a PASSED                              [ 25%]
test_setup.py::TestSomething::test_b PASSED                              [ 50%]
test_setup.py::TestSomethingElse::test_a SKIPPED                         [ 75%]
Skipped: Test not needed

test_setup.py::TestSomethingElse::test_b SKIPPED                         [100%]
Skipped: Test not needed