Добавление маркеров pytest для тестирования в зависимости от используемых приспособлений

#python #pytest #fixtures

#python #pytest #приспособления

Вопрос:

Я ищу способ пометить тесты pytest маркерами в зависимости от того, какие устройства использует этот тест.

Я хотел бы использовать это для фильтрации тестов на основе используемых ими функций. Например: тест, который использует приспособление «database_connection», должен автоматически помечаться как «база данных». Таким образом, я мог бы включать или исключать все такие тесты в зависимости от того, имеются ли учетные данные базы данных.

Это то, что у меня сейчас есть:

 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."""
  

Это работает именно так, как я хочу, но мне не нравится поддерживать отображение от приспособления к метке, отделенное от самого приспособления. Что я хотел бы сделать, так это украсить приборы маркерами, которые должны быть установлены во всех тестах, которые их используют. Это должно выглядеть так:

 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."""
  

Конечно, я мог бы создать декоратор, который хранит отображение в глобальной переменной:

 _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."""
  

Однако это кажется немного странным. Я почти уверен, что это не странный случай использования, и может быть какая-то функция pytest, которая уже предоставляет то, что мне нужно.

У кого-нибудь есть идея, как реализовать это простым способом?

Ответ №1:

Есть простое решение, которое, похоже, работает. Хитрость заключается в том, чтобы заметить, что вы можете параметризовать устройства и отмечать параметры. Вы можете просто игнорировать параметр. Например:

 @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):
    ...
  

автоматически отметит любой тест, который использует database_connection , db меткой.