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

Как используется генератор в pytest fixture?

2.0 Middle🔥 221 комментариев
#Тестирование

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

Генератор в pytest fixture

Генераторы в pytest fixtures используются для setup и teardown ресурсов.

Базовый пример

import pytest

@pytest.fixture
def database():
    # Setup (до теста)
    db = connect_to_database()
    print("Database connected")
    
    yield db  # Отправляем ресурс в тест
    
    # Teardown (после теста)
    db.close()
    print("Database closed")

def test_query(database):
    result = database.query("SELECT * FROM users")
    assert len(result) > 0

# Порядок выполнения:
# 1. Database connected
# 2. test_query(db)
# 3. Database closed

Контроль ресурсов

@pytest.fixture
def temp_file():
    # Setup: создать файл
    with open('/tmp/test.txt', 'w') as f:
        f.write('test data')
    
    yield '/tmp/test.txt'  # Передать путь в тест
    
    # Teardown: удалить файл
    os.remove('/tmp/test.txt')

def test_read_file(temp_file):
    with open(temp_file) as f:
        content = f.read()
    assert 'test' in content

С contextmanager

from contextlib import contextmanager

@contextmanager
def database_connection():
    db = connect()
    try:
        yield db
    finally:
        db.close()

@pytest.fixture
def db():
    with database_connection() as database:
        yield database

Autouse (автоматическое использование)

@pytest.fixture(autouse=True)
def cleanup():
    # Этот fixture автоматически применится ко всем тестам
    yield
    # Cleanup код после каждого теста
    print("Cleanup after each test")

def test_something():
    pass  # cleanup выполнится автоматически

Scope и fixture

@pytest.fixture(scope="module")  # На весь модуль
def expensive_resource():
    resource = create_expensive_resource()
    yield resource
    # Cleanup только один раз в конце модуля
    resource.cleanup()

@pytest.fixture(scope="function")  # На каждый тест (default)
def simple_fixture():
    yield "value"
    # Cleanup после каждого теста

Обработка ошибок

@pytest.fixture
def safe_database():
    db = None
    try:
        db = connect()
        yield db
    finally:
        if db:
            db.close()  # Гарантированное закрытие

# Даже если тест упадёт, cleanup выполнится

Множественные yield

# Неправильно: только первый yield работает
@pytest.fixture
def multi_yield():
    yield "first"
    yield "second"  # Это не будет использовано

# Правильно: используй параметризацию
@pytest.fixture(params=["first", "second"])
def multi_param(request):
    yield request.param

Практический пример: API mock

import responses

@pytest.fixture
def mock_api():
    # Setup: активировать responses mock
    responses.start()
    responses.add(
        responses.GET,
        'https://api.example.com/users/1',
        json={'id': 1, 'name': 'John'},
        status=200
    )
    
    yield  # Тест выполняется с активным mock
    
    # Teardown: деактивировать responses
    responses.stop()
    responses.reset()

def test_api_call(mock_api):
    response = requests.get('https://api.example.com/users/1')
    assert response.json()['name'] == 'John'

Вложенные fixtures

@pytest.fixture
def app():
    app = create_app()
    yield app
    app.teardown()

@pytest.fixture
def client(app):
    # Использует другой fixture
    yield app.test_client()

def test_api(client):
    response = client.get('/')
    assert response.status_code == 200

Вывод: Генератор в pytest fixture позволяет элегантно управлять setup и teardown ресурсов, гарантируя их освобождение даже при ошибках тестов.

Как используется генератор в pytest fixture? | PrepBro