Загружаем изображение…

Pytest Patterns: Элегантный Teardown через yield и оптимизация скоупов



Если вы все еще пишете def teardown_method(self): в классах тестов, вы не используете мощь Pytest на 100%.
Фикстуры (fixtures) - это не просто способ передать данные. Это полноценный механизм управления жизненным циклом зависимостей (DI).

1. yield вместо return: Встроенный Teardown
В Pytest фикстура может "замереть", отдать управление тесту, а потом продолжить выполнение. Это реализуется через генератор yield.

Код до yield - это setUp.
Код после yield - это tearDown.

Пример (временная база данных):

import pytest
from sqlalchemy import create_engine

@pytest.fixture
def db_engine():
# Setup: Поднимаем соединение
engine = create_engine("sqlite:///:memory:")

# Передаем объект в тест
yield engine

# Teardown: Этот код выполнится ПОСЛЕ завершения теста
# (даже если тест упал с ошибкой!)
engine.dispose()


Это гарантирует, что ресурсы будут освобождены, и вам не нужны try/finally блоки внутри самих тестов.

2. Scopes: Не создавайте мир заново
По умолчанию фикстура имеет scope='function'. Она создается и умирает для каждого теста. Это безопасно, но медленно, если мы говорим о поднятии Docker-контейнера или коннекта к БД.

Используйте scope='session' для тяжелых ресурсов, которые можно переиспользовать.

Паттерн "Изоляция при общем ресурсе":
Частая задача Middle+: иметь одну БД на весь прогон тестов (быстро), но чистые таблицы для каждого теста (изолированно).

Решение: комбинируем скоупы.

# Живет весь прогон тестов (создается 1 раз)
@pytest.fixture(scope="session")
def db_engine():
engine = create_engine(...)
yield engine
engine.dispose()

# Живет 1 тест (создается N раз)
@pytest.fixture(scope="function")
def db_session(db_engine):
# Берем engine из сессионной фикстуры
connection = db_engine.connect()
transaction = connection.begin() # Начали транзакцию

session = Session(bind=connection)
yield session

session.close()
# ROLLBACK транзакции после теста вернет базу в исходное состояние!
transaction.rollback()
connection.close()


Итог:

🟢 Используйте yield для очистки ресурсов.
🟢 Тяжелые объекты (Engine, Client, Container) - в scope='session'.
🟢 Легкие объекты с состоянием (Session, User) - в scope='function', наследуясь от тяжелых.

#pytest #testing #qa #bestpractices #python

👉 @BookPython
Просмотры: 6 963
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти