根据使用的装置添加 pytest 标记进行测试

Tim*_*ler 12 python fixtures pytest

我正在寻找一种方法来使用标记来标记 pytest 测试,具体取决于此测试使用的固定装置。

我想用它来根据测试使用的功能来过滤测试。例如:使用“database_connection”装置的测试应自动标记为“database”。这样,我可以根据数据库凭据是否在手,包含或排除所有此类测试。

这就是我目前所拥有的:

def pytest_configure(config):
    """Register hook to extend the list of available markers."""
    config.addinivalue_line("markers", "database: mark test that need a database connection.")

def pytest_collection_modifyitems(config, items):  # pylint: disable=unused-argument
    """Register hook to map used fixtures to markers."""
    for item in items:
        if "database_connection" in item.fixturenames:
            database_marker = pytest.mark.database()
            item.add_marker(database_marker)

@pytest.fixture
def database_connection():
    """Fixture providing a database connection."""
Run Code Online (Sandbox Code Playgroud)

这正是我想要的方式,但我不喜欢必须维护从夹具到标记的映射与夹具本身分开。我想做的是用标记来装饰固定装置,这些标记应该在使用它们的所有测试上设置。它应该看起来像这样:

def pytest_configure(config):
    """Register hook to extend the list of available markers."""
    config.addinivalue_line("markers", "database: mark test that need a database connection.")

def pytest_collection_modifyitems(config, items):  # pylint: disable=unused-argument
    """Register hook to map used fixtures to markers."""
    for item in items:
        for fixture in item.fixtures:
            item.add_markers(fixture.markers)         

@pytest.fixture(markers=["database"])
def database_connection():
    """Fixture providing a database connection."""
Run Code Online (Sandbox Code Playgroud)

当然,我可以构建一个装饰器,将映射存储在全局变量中:

_fixture_marker_map = {}

def set_markers(*markers):
    def decorator_set_markers(func):
        _fixture_marker_map[func.__name__] = markers
        
        @functools.wraps(func)
        def wrapper_set_markers(*args, **kwargs):
            return func(*args, **kwargs)
        return wrapper_set_markers
    return decorator_set_markers

@set_markers("database")
@pytest.fixture
def database_connection():
    """Fixture providing a database connection."""
Run Code Online (Sandbox Code Playgroud)

然而,这感觉有点hacky。我很确定这不是一个奇怪的用例,并且可能有一些 pytest 功能已经提供了我需要的东西。

有谁知道如何以简单的方式实现这一点?

san*_*ton 5

有一个简单的解决方案似乎有效。诀窍是注意您可以对灯具进行参数化并标记参数。您可以忽略该参数。例如:

@pytest.fixture(params=[pytest.param(None, marks=pytest.mark.db))
def database_connection(request):
    """Fixture providing a database connection."""
    ...


def test_db_connection(database_connection):
    ...
Run Code Online (Sandbox Code Playgroud)

将自动标记任何使用该database_connection标记的测试db