【问题标题】:Cleaner way to do pytest fixture parameterization based on command-line switch?基于命令行开关的 pytest 夹具参数化的更清洁方法?
【发布时间】:2018-03-22 05:45:34
【问题描述】:

我在技术上已经解决了我正在解决的问题,但我不禁觉得我的解决方案很丑:

我有一个 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() 在测试完成时永远不会被调用。使用 dummy 可以让我用参数元组替换 dummy,以便将其传递到 driver()

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

【问题讨论】:

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


    【解决方案1】:

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

    # 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 测试取消选择那么优雅,并且更适合复杂的运行时条件,而不是先验已知的测试结构。

    【讨论】:

    • 这绝对比假夹具好!有没有办法用超过 2 个配置标记进行设置(即,我可以有任意数量的模式,例如基准测试、标准 CI 套件、超级超级硬核预发布套件)?
    猜你喜欢
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 2023-03-03
    相关资源
    最近更新 更多