Ответ
Функция-генератор в Python — это специальная функция, которая возвращает итератор (генератор) и позволяет лениво генерировать последовательность значений. Вместо ключевого слова return она использует yield. При каждом вызове next() у генератора функция выполняется до следующего yield, возвращает значение и приостанавливается, сохраняя своё состояние до следующего вызова.
Зачем это нужно в тестировании? Генераторы полезны для создания больших или бесконечных потоков тестовых данных без загрузки всей последовательности в память сразу.
Пример: Генератор тестовых данных для проверки граничных значений:
def generate_test_ids(start=1, step=100):
"""Генератор, который выдаёт идентификаторы для тестов."""
current_id = start
while True: # Бесконечная последовательность
yield current_id
current_id += step
# Использование в тесте
id_generator = generate_test_ids()
test_data = [
(next(id_generator), "valid"), # 1
(next(id_generator), "valid"), # 101
(0, "invalid"), # Граничное значение 0
(-1, "invalid"), # Отрицательное значение
]
@pytest.mark.parametrize("user_id, expected_status", test_data)
def test_user_by_id(api_client, user_id, expected_status):
response = api_client.get(f"/users/{user_id}")
if expected_status == "valid":
assert response.status_code == 200
else:
assert response.status_code == 404
Пример: Генератор для чтения большой тестовой лог-файла построчно:
def read_large_log_file(file_path):
"""Генератор для ленивого чтения большого файла построчно."""
with open(file_path, 'r') as file:
for line in file:
# Можно добавить фильтрацию
if "ERROR" in line:
yield line.strip() # Возвращаем только строки с ошибками
# В тесте проверяем наличие критических ошибок в логе
def test_log_has_no_critical_errors():
error_lines = list(read_large_log_file("app.log"))
for error in error_lines:
assert "CRITICAL" not in error, f"Found critical error: {error}"
Ключевые отличия от обычной функции:
- Ленивые вычисления: Значения генерируются по требованию.
- Экономия памяти: Не нужно хранить всю последовательность в памяти.
- Сохранение состояния: Функция "помнит" своё место между вызовами.