Как тестировать поля в ответе при наличии только GET запроса и отсутствии возможности подготовить тестовые данные
Что проверяют
Умеете ли вы проверять API, когда нельзя положить в базу известную запись и сравнить ответ с ней. Интервьюер хочет услышать, что без эталонных данных проверяют контракт и инварианты, а не конкретные значения. Следом спрашивают, откуда тогда брать ожидаемый результат.
Как отвечать
Разделите проверки на уровни:
- контракт: статус,
Content-Type, обязательные поля, типы, форматы. Удобно описать ответ модельюpydanticи вызватьModel.model_validate(resp.json())или сверить с JSON Schema черезjsonschema. Если есть OpenAPI-спецификация,schemathesisсам сгенерирует запросы и проверит ответы по схеме; - инварианты: правила, верные для любых данных.
idуникальны,created_atв ISO 8601 и не в будущем,totalравен сумме позиций, при?status=activeв выдаче нет других статусов, сортировка соблюдена, страницы пагинации не пересекаются; - согласованность: элемент из
/itemsсовпадает с/items/{id}, полеcountсовпадает с реальным числом записей; - живые данные: сначала запросите список, возьмите реальный
idи работайте с ним. Если есть доступ на чтение к базе или реплике, ожидаемое значение берётся SQL-запросом; - негатив: несуществующий
idдаёт 404, кривой параметр 400 или 422, но не 500.
Для регрессии годятся снапшоты: сохранили ответ (например, плагином syrupy для pytest), вычистили изменчивые поля вроде дат и сравниваете при следующем прогоне.
Сами тесты пишутся на pytest с requests или httpx, наборы параметров выносятся в @pytest.mark.parametrize.
Где спотыкаются
Мокают requests.get и проверяют мок. Такой тест проверяет сам себя и пройдёт, даже если сервер лежит.
Хардкодят значения из сегодняшних данных. Завтра запись изменится, и тест упадёт без всякого бага.
Проверяют только наличие поля, но не тип. "price": "100" строкой вместо числа ломает клиентов, а проверка in этого не заметит.