Какие уровни видимости (scope) существуют для фикстур в pytest

Ответ

В pytest параметр scope у декоратора @pytest.fixture определяет жизненный цикл фикстуры — как часто она будет создаваться и уничтожаться.

Существуют следующие уровни scope (от самого узкого к самому широкому):

  • function: (По умолчанию) Фикстура выполняется для каждой тестовой функции. Обеспечивает максимальную изоляцию тестов.
  • class: Фикстура выполняется один раз на тестовый класс.
  • module: Фикстура выполняется один раз на модуль (файл).
  • package: Фикстура выполняется один раз на пакет (директорию с __init__.py).
  • session: Фикстура выполняется один раз на всю тестовую сессию.

Как выбрать правильный scope?

Выбор зависит от ресурсоемкости инициализации и необходимости изоляции.

  • Используйте function для полной изоляции, когда каждый тест должен работать с "чистым" состоянием.
  • Используйте module или session для "тяжелых" ресурсов (например, подключение к БД, запуск Docker-контейнера), инициализация которых занимает много времени. Это значительно ускоряет выполнение тестов.

Пример (scope='module'):

import pytest

# Эта фикстура будет вызвана только один раз для всего файла
@pytest.fixture(scope='module')
def db_connection():
    print("nУстановка соединения с БД...")
    conn = create_db_connection() # Условная функция
    yield conn
    print("nЗакрытие соединения с БД...")
    conn.close()

# Оба теста будут использовать один и тот же экземпляр db_connection
def test_query1(db_connection):
    assert db_connection.execute("SELECT 1") is not None

def test_query2(db_connection):
    assert db_connection.execute("SELECT 2") is not None

Важно: фикстуры с широким scope (module, session) должны быть потокобезопасными при параллельном запуске тестов (например, с pytest-xdist).