运行 使用一组标记进行测试,这些标记是根据命令行参数的值选择的

Run tests with a set of marks, which selected based on command line parameter's value

我有以下测试:

@pytest.mark.hardware
@pytest.mark.feature1
@pytest.mark.feature2
def test_device1():
    pass

@pytest.mark.hardware
@pytest.mark.feature1
def test_device2():
    pass

@pytest.mark.hardware
@pytest.mark.feature2
def test_device3():
    pass

目标:如果我在命令行参数上指定:pytest --device device1 ,我希望只测试带有标记 feature1、feature2、硬件的测试将是 运行。类似地:参数 device2 只会唤起带有标记 hardware 和 feature1 等的测试。如果没有参数,没有标记的测试将是 运行.

在 conftest.py 我有:

def pytest_addoption(parser):
    group = parser.getgroup("filter")
    group.addoption(
        "--device",
        action="store",
        help="specify the device",
    )

我发现 pytest_collection_modifyitems 可能有帮助,但我不知道如何根据命令行参数的值 select 标记列表 运行 。在此先感谢您的帮助。

我试过了,但没有成功:

def pytest_collection_modifyitems(config, items):
    if config.getoption("--device") == 'device2':
        for item in items:
            item.add_marker(pytest.mark.hardware)
            item.add_marker(pytest.mark.feature1)

您必须根据 device 选项条件过滤 items 列表。实施例:

def marker_names(item):
    return set(m.name for m in item.iter_markers())


def pytest_collection_modifyitems(config, items):
    device_markers = {
        "device1": {"feature1", "feature2", "hardware"},
        "device2": {"feature1", "hardware"},
    }

    device_option = config.getoption("--device")

    if device_option is None:
        items[:] = [item for item in items if not list(item.iter_markers())]
    else:
        allowed_markers = device_markers[device_option]
        items[:] = [item for item in items if marker_names(item) == allowed_markers]

您也可以跳过测试而不是将它们排除在外。实施例:

def marker_names(item):
    return set(m.name for m in item.iter_markers())


def pytest_collection_modifyitems(config, items):
    device_markers = {
        "device1": {"feature1", "feature2", "hardware"},
        "device2": {"feature1", "hardware"},
    }

    device_option = config.getoption("--device")

    if device_option is None:
        for item in items:
            if list(item.iter_markers()):
                item.add_marker(pytest.mark.skip("has no markers"))
    else:
        allowed_markers = device_markers[device_option]
        for item in items:
            if marker_names(item) != allowed_markers:
                item.add_marker(pytest.mark.skip(f"has some markers missing for {device_option}"))