Ответ
Использование yield в фикстурах pytest — это идиоматичный способ управления ресурсами, которые требуют явной инициализации (setup) и последующей очистки (teardown).
Этот паттерн разделяет фикстуру на три части:
- Setup: Код, выполняемый до
yield. Здесь происходит создание и настройка ресурса (например, подключение к БД, запуск веб-драйвера, создание временного файла). - Yield: Ключевое слово, которое передает созданный ресурс в тест и приостанавливает выполнение фикстуры.
- 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.