Pytest Patterns: Элегантный Teardown через
Если вы все еще пишете
Фикстуры (fixtures) - это не просто способ передать данные. Это полноценный механизм управления жизненным циклом зависимостей (DI).
1.
В Pytest фикстура может "замереть", отдать управление тесту, а потом продолжить выполнение. Это реализуется через генератор
Код до
Код после
Пример (временная база данных):
Это гарантирует, что ресурсы будут освобождены, и вам не нужны
2. Scopes: Не создавайте мир заново
По умолчанию фикстура имеет
Используйте
Паттерн "Изоляция при общем ресурсе":
Частая задача Middle+: иметь одну БД на весь прогон тестов (быстро), но чистые таблицы для каждого теста (изолированно).
Решение: комбинируем скоупы.
Итог:
🟢 Используйте
🟢 Тяжелые объекты (Engine, Client, Container) - в
🟢 Легкие объекты с состоянием (Session, User) - в
#pytest #testing #qa #bestpractices #python
📲 Мы в MAX
👉@BookPython
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 для очистки ресурсов.scope='session'.scope='function', наследуясь от тяжелых.#pytest #testing #qa #bestpractices #python
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1