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

2024-10-02 12:26:31 发布

您现在位置:Python中文网/ 问答频道 /正文

技术上我已经解决了我正在解决的问题,但我还是忍不住觉得我的解决方案很难看:

我有一个pytest套件,可以在两种模式下运行:本地模式(用于开发测试;所有东西都通过Chrome运行在我的dev-box上)和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直接参数化driverfixture,但它最终会用替换fixture,而不是仅仅向它输入内容,因此在测试结束时,cleanup()永远不会被调用。使用dummy可以让我用参数元组替换这个dummy,这样它就被传递到driver()。在

但是,重申一下,我所拥有的东西确实有效,这感觉就像是一次简陋的黑客攻击。在


Tags: oftestfalse套件pytestlocaldefdriver
1条回答
网友
1楼 · 发布于 2024-10-02 12:26:31

您可以尝试一种不同的方法:不是动态地为测试选择参数集,而是声明其中的所有参数集,但在启动时取消选择不相关的参数集。在

# 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])

然后按如下方式运行:

^{pr2}$

此外,skipif标记可用于所选参数集(与取消选择不同)。它们由pytest本机支持。但是语法很难看。更多信息请参见pytest的Skip/xfail with parametrize部分。在

官方手册中也包含了与你在Custom marker and command line option to control test runs中的问题完全相同的情况。然而,它也不像-m测试取消选择那样优雅,而且更适合于复杂的运行时条件,而不是基于先验已知的测试结构。在

相关问题 更多 >

    热门问题