更清洁的方法来进行基于命令行开关的pytest夹具参数化?

时间:2017-10-10 18:05:35

标签: python command-line-arguments pytest fixtures parameterization

我在技术上已经解决了我正在解决的问题,但我无法帮助,但觉得我的解决方案很难看:

我有一个pytest套件,我可以在两种模式下运行:本地模式(用于开发测试;一切只需通过Chrome在我的开发盒上运行),以及Seriousface回归测试模式(用于CI;套件得到)在众多浏览器和操作系统上运行)。我有一个命令行标志,可以在两种模式--test-local之间切换。如果它在那里,我在本地模式下运行。如果它不存在,我会以严肃面模式运行。以下是我的表现方式:

# contents of conftest.py
import pytest

def pytest_addoption(parser):
    parser.addoption("--test-local", action="store_true", default=False, help="run locally instead of in seriousface mode")

def pytest_generate_tests(metafunc):
    if "dummy" in metafunc.fixturenames:
        if metafunc.config.getoption("--test-local"):
            driverParams = [(True, None)]
        else:
            driverParams = [(False, "seriousface setting 1"), (False, "seriousface setting 2")]
        metafunc.parameterize("dummy", driverParams)

@pytest.fixture(scope="function")
def driver(dummy):
    _driver = makeDriverStuff(dummy[0], dummy[1])
    yield _driver
    _driver.cleanup()

@pytest.fixture
def dummy():
    pass

问题是,dummy夹具很可怕。我已尝试直接pytest_generate_tests driver固定cleanup()夹具,但它最终替换夹具,而不仅仅是将材料送入其中,因此driver()测试结束时永远不会被调用。使用虚拟对象让我用我的参数元组替换虚拟对象,以便将其传递到Record Example := { fieldA : nat; fieldB : nat }.

但是,重申一下,我所拥有的确实有效,它只是感觉像是一个笨拙的黑客。

1 个答案:

答案 0 :(得分:2)

您可以尝试不同的方法:不是动态选择测试的参数集,而是在其上声明所有参数集,但在发布时取消选择不相关的参数集。

# r.py
import pytest

real = pytest.mark.real
mock = pytest.mark.mock

@pytest.mark.parametrize('a, b', [
    real((True, 'serious 1')),
    real((True, 'serious 2')),
    mock((False, 'fancy mock')),
    (None, 'always unmarked!'),
])
def test_me(a, b):
    print([a, b])

然后按如下方式运行:

pytest -ra -v -s   r.py -m real        # strictly marked sets
pytest -ra -v -s   r.py -m mock        # strictly marked sets
pytest -ra -v -s   r.py -m 'not real'  # incl. non-marked sets
pytest -ra -v -s   r.py -m 'not mock'  # incl. non-marked sets

此外,skipif标记可用于所选参数集(与取消选择不同)。它们由pytest本地支持。但语法非常难看。请参阅pytest的Skip/xfail with parametrize部分中的更多内容。

官方手册中也包含与Custom marker and command line option to control test runs中的问题完全相同的案例。但是,它也不如-m测试取消选择那么优雅,并且更适合于复杂的运行时条件,而不适用于先验已知的测试结构。