Какую роль играет параметр scope у фикстур в pytest

Ответ

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

Выбор правильного scope критически важен для оптимизации скорости тестов и управления ресурсами, особенно для "дорогих" операций, таких как подключение к базе данных или запуск внешнего сервиса.

Доступные значения scope (от краткосрочного к долгосрочному):

  • 'function' (по умолчанию): Фикстура создается для каждой тестовой функции и уничтожается после ее завершения.
  • 'class': Фикстура создается один раз для всех тестов в классе.
  • 'module': Фикстура создается один раз для всех тестов в файле (модуле).
  • 'package': Фикстура создается один раз для всех тестов в пакете (директории).
  • 'session': Фикстура создается один раз в начале всей тестовой сессии и уничтожается в самом конце.

Практический пример:

Предположим, у нас есть тесты, требующие подключения к базе данных. Создавать новое подключение для каждого теста (scope='function') очень медленно. Вместо этого мы можем создать одно подключение на весь модуль.

import pytest

# Эта фикстура будет выполнена только один раз для всего файла
@pytest.fixture(scope='module')
def db_connection():
    print("n[+] Создание подключения к БД...")
    conn = create_expensive_db_connection()
    yield conn # Тесты получают объект подключения
    print("n[-] Закрытие подключения к БД...")
    conn.close()

# Оба теста будут использовать ОДИН И ТОТ ЖЕ объект db_connection
def test_user_query(db_connection):
    assert db_connection.execute("SELECT * FROM users") is not None

def test_items_query(db_connection):
    assert db_connection.execute("SELECT * FROM items") is not None

В этом примере подключение к БД будет установлено один раз перед запуском test_user_query и закрыто только после завершения test_items_query, что значительно ускоряет выполнение тестов.