← Назад к вопросам

Что можно записать в фикстуру?

2.3 Middle🔥 161 комментариев
#Теория тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что можно вынести в фикстуру в Pytest?

В контексте pytest (наиболее популярного фреймворка для тестирования в Python) фикстуры (fixtures) — это мощный механизм для инъекции зависимостей, который позволяет выносить общий код для подготовки, выполнения и очистки тестов. Основная цель — повышение модульности, читаемости и поддерживаемости тестового кода, а также исключение дублирования.

Основные категории данных и логики для выноса в фикстуры:

1. Подготовка тестовых данных

  • Статические данные: Константы, простые структуры данных (словари, списки), которые используются в нескольких тестах.
    @pytest.fixture
    def valid_user_data():
        return {"username": "test_user", "email": "user@example.com"}
    
  • Динамические данные: Данные, генерируемые на лету (например, с использованием библиотеки Faker), или данные, зависящие от текущего времени.
    @pytest.fixture
    def random_email(faker):
        return faker.email()
    
  • Загрузка данных из файлов: Конфигурационные файлы (JSON, YAML), ожидаемые результаты, большие наборы данных.
    import json
    @pytest.fixture
    def config_data():
        with open('config.json') as f:
            return json.load(f)
    

2. Работа с тестовым окружением и внешними зависимостями

  • Инициализация и очистка ресурсов: Самая классическая и важная область. Например, создание и закрытие подключения к БД, запуск и остановка Selenium WebDriver, мокание внешних сервисов.
    @pytest.fixture
    def database_connection():
        conn = create_db_connection()  # setup
        yield conn  # предоставление ресурса тесту
        conn.close()  # teardown (выполнится после теста)
    
  • Временные файлы и директории: Использование встроенной фикстуры tmp_path для создания изолированных файлов для каждого теста.
  • Подмена (Mock/Stub) внешних API: Создание мок-объектов для HTTP-клиентов, платежных шлюзов и т.д., чтобы изолировать тест от нестабильной внешней среды.
    import pytest
    from unittest.mock import Mock
    @pytest.fixture
    def mock_http_client():
        client = Mock()
        client.get.return_value.status_code = 200
        return client
    

3. Управление состоянием приложения (особенно актуально для QA Automation)

  • Предусловия тестов: Действия, необходимые для приведения системы в нужное состояние перед тестом. Например, создание пользователя в системе, добавление товара в корзину, публикация статьи.
    @pytest.fixture
    def registered_user(api_client):
        user_data = {"name": "AutoUser"}
        response = api_client.post("/users/", json=user_data)
        return response.json()  # возвращает созданного пользователя
    
  • Постусловия и очистка: Действия, выполняемые после теста, чтобы не засорять окружение. Например, удаление созданного пользователя, отмена тестового заказа. Часто совмещается с подготовкой через yield.
    @pytest.fixture
    def clean_test_order(api_client):
        order_ids = []
        def _create_order(data):
            resp = api_client.post("/orders/", json=data)
            order_id = resp.json()['id']
            order_ids.append(order_id)
            return resp
        yield _create_order  # тест получает функцию для создания
        # После теста удаляем все созданные заказы
        for oid in order_ids:
            api_client.delete(f"/orders/{oid}")
    

4. Конфигурация и настройки

  • Параметры запуска: Получение значений из командной строки (pytest.addoption) или переменных окружения для условной логики в тестах (например, выбор URL для тестирования: prod/staging).
    @pytest.fixture(scope="session")
    def base_url(request):
        env = request.config.getoption("--env")
        return f"https://{env}.example.com"
    
  • Общие настройки библиотек: Конфигурация логгера, инициализация клиента REST API с общими заголовками (Content-Type, Authorization).
    @pytest.fixture
    def api_client():
        client = APIClient(base_url="https://api.example.com")
        client.headers.update({"Authorization": "Bearer test_token"})
        return client
    

Ключевые принципы при работе с фикстурами:

  • Многоразовость: Фикстура должна быть спроектирована так, чтобы ее могло использовать множество тестов.
  • Изоляция: По возможности тесты не должны влиять друг на друга через состояние, созданное фикстурой. Используйте соответствующую область видимости (scope).
    *   `function` (по умолчанию) — для каждого теста.
    *   `class` — для всех тестов класса.
    *   `module` — для всех тестов в модуле.
    *   `session` — один раз за весь прогон.
  • Четкие зависимости: Тест должен явно объявлять нужные ему фикстуры в параметрах. Это делает зависимости наглядными.
  • Автоочистка (teardown): Использование yield или request.addfinalizer для гарантированного освобождения ресурсов даже в случае падения теста.

Пример комплексной фикстуры для UI-автотеста:

import pytest
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options

@pytest.fixture(scope="function") # Для каждого теста новый браузер
def driver():
    options = Options()
    options.add_argument("--headless") # Конфигурация
    driver_instance = Chrome(options=options) # Инициализация ресурса
    driver_instance.implicitly_wait(10)
    yield driver_instance # Передача управления тесту
    driver_instance.quit() # Очистка после теста

# Тест использует фикстуру как зависимость
def test_login(driver):
    driver.get("https://example.com/login")
    # ... действия теста
    assert driver.current_url == "https://example.com/dashboard"

Таким образом, в фикстуру целесообразно выносить любой код, который является общим для двух и более тестов, а также логику подготовки (setup) и очистки (teardown) тестового окружения. Это превращает фикстуры в централизованный и легко управляемый инструмент для построения надежной и масштабируемой автоматизации.