Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于命令行开关的pytest夹具参数化的更简洁方法?_Python_Command Line Arguments_Pytest_Fixtures_Parameterization - Fatal编程技术网

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

Python 基于命令行开关的pytest夹具参数化的更简洁方法?,python,command-line-arguments,pytest,fixtures,parameterization,Python,Command Line Arguments,Pytest,Fixtures,Parameterization,从技术上讲,我已经解决了我正在解决的问题,但我忍不住觉得我的解决方案很难看: 我有一个pytest套件,我可以在两种模式下运行:本地模式(用于开发测试;所有东西都通过Chrome在我的dev box上运行)和Seriousface回归测试模式(用于CI;该套件可以在无数浏览器和操作系统上运行)。我有一个命令行标志在两种模式之间切换,--testlocal。如果它在那里,我在本地模式下运行。如果它不在那里,我会以严肃的面部模式运行。我是这样做的: # contents of conftest.py

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

我有一个pytest套件,我可以在两种模式下运行:本地模式(用于开发测试;所有东西都通过Chrome在我的dev box上运行)和Seriousface回归测试模式(用于CI;该套件可以在无数浏览器和操作系统上运行)。我有一个命令行标志在两种模式之间切换,
--testlocal
。如果它在那里,我在本地模式下运行。如果它不在那里,我会以严肃的面部模式运行。我是这样做的:

# 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
fixture很可怕。我曾尝试让
pytest\u generate\u tests
直接参数化
驱动程序
夹具,但它最终会替换夹具,而不是仅仅向夹具中添加内容,因此在测试完成时,
cleanup()
永远不会被调用。使用虚拟对象可以将虚拟对象替换为参数元组,这样就可以将参数元组传递到
driver()


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

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

# 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一节中的更多内容


官方手册也包含与您在中的问题完全相同的案例。然而,它也不像
-m
测试取消选择那样优雅,更适合复杂的运行时条件,而不是先验已知的测试结构。

这肯定比虚拟夹具更好!是否有方法设置超过2个配置标记(即,我可以有任意数量的模式,例如benchtesting、standard CI suite、super mega hardcore Pre Release suite)?