Для чего в фикстурах pytest используется yield

«Для чего в фикстурах pytest используется yield» — вопрос из категории Тестирование, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Использование yield в фикстурах pytest — это идиоматичный способ управления ресурсами, которые требуют явной инициализации (setup) и последующей очистки (teardown).

Этот паттерн разделяет фикстуру на три части:

  1. Setup: Код, выполняемый до yield. Здесь происходит создание и настройка ресурса (например, подключение к БД, запуск веб-драйвера, создание временного файла).
  2. Yield: Ключевое слово, которое передает созданный ресурс в тест и приостанавливает выполнение фикстуры.
  3. Teardown: Код, выполняемый после yield. Он гарантированно выполняется после завершения теста (даже если тест упал), обеспечивая корректное освобождение ресурса (закрытие соединения, удаление файла).

Пример с подключением к базе данных:

import pytest

class DatabaseConnection:
    def __init__(self, dsn):
        print(f"n[SETUP] Connecting to {dsn}...")
        self._connection = "<connection_object>"

    def query(self, sql):
        return f"Executing '{sql}'"

    def close(self):
        print("n[TEARDOWN] Closing connection...")

@pytest.fixture(scope="module")
def db_connection():
    # 1. Setup-фаза
    conn = DatabaseConnection("postgresql://user:pass@host/db")

    # 2. Передача ресурса в тест
    yield conn

    # 3. Teardown-фаза (гарантированно выполнится)
    conn.close()

def test_user_query(db_connection):
    result = db_connection.query("SELECT * FROM users")
    assert "users" in result

Этот подход является более чистой и надежной альтернативой addfinalizer, так как логика setup и teardown находится в одном месте и работает аналогично конструкции try...finally.