#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
меткой.