Ответ
В PyTest yield и return используются в фикстурах для передачи данных в тест, но с фундаментальным отличием в возможности выполнить код очистки (teardown) после завершения теста.
Фикстура с return
- Передаёт значение в тест и завершает работу.
- Не предоставляет встроенного механизма для очистки. Если ресурс нужно закрыть, это делается отдельно (например, в финальной фазе теста или с помощью
request.addfinalizer).
Фикстура с yield
- Работает как генератор. Код до
yieldвыполняется как установка (setup), а код послеyield— как очистка (teardown). - Очистка выполняется гарантированно, даже если тест упал с ошибкой (assertion или exception).
- Это идеальный способ для работы с ресурсами, требующими закрытия (файлы, соединения с БД, браузеры).
Практический пример с временным файлом:
import pytest
import os
# Фикстура с yield (рекомендуемый способ для ресурсов)
@pytest.fixture
def temp_config_file():
# SETUP: Создаём временный файл перед тестом
file_path = "/tmp/test_config.yaml"
with open(file_path, 'w') as f:
f.write("test_key: test_value")
print("Файл создан")
yield file_path # Передаём путь к файлу в тест
# TEARDOWN: Удаляем файл после теста (выполнится всегда)
os.remove(file_path)
print("Файл удалён")
# Фикстура с return и addfinalizer (альтернативный способ)
@pytest.fixture
def temp_config_file_v2(request):
file_path = "/tmp/test_config_v2.yaml"
with open(file_path, 'w') as f:
f.write("test_key: test_value")
print("Файл v2 создан")
def cleanup():
os.remove(file_path)
print("Файл v2 удалён")
request.addfinalizer(cleanup) # Регистрируем функцию очистки
return file_path # Передаём путь
# Тест использует фикстуру
def test_read_config(temp_config_file):
# В тест передан file_path
with open(temp_config_file) as f:
content = f.read()
assert "test_key" in content
# После этого теста PyTest автоматически выполнит os.remove(file_path)
Вывод: Для управления жизненным циклом ресурсов (открыть/закрыть) всегда используйте фикстуры с yield. return подходит для простых данных, не требующих очистки.