Урок по треку Автоматизация тестирования 8 мин

API-автотесты за 8 минут

Клиент, проверки ответа, схемы, тестовые данные, контрактные тесты.

API-тесты основная масса автотестов в нормальной пирамиде: они в десятки раз быстрее UI, почти не флакают и проверяют бизнес-логику напрямую. Ручное тестирование API разбирается в треке «Тестирование API», здесь про то, как это автоматизировать.

Стек

  • Python: requests или httpx + pytest, схемы через pydantic или jsonschema.
  • Java: REST Assured (given().when().then()) + JUnit 5 или TestNG.
  • JS/TS: фикстура request в Playwright, supertest, axios + Vitest.
  • Postman-коллекции в CI запускают через Newman, но для большого набора код удобнее: ревью, переиспользование, типы.

Слои

tests/        сценарии и проверки
clients/      по клиенту на сервис: методы create_order(), get_order()
models/       схемы ответов (pydantic) и билдеры запросов
conftest.py   базовый URL, авторизация, фабрики данных

Тест не должен собирать URL и заголовки руками. Он зовёт orders.create(...), а клиент знает путь, авторизацию и логирует запрос и ответ в отчёт.

Что проверять в ответе

  1. Статус: ровно ожидаемый (201, а не «любой 2xx»).
  2. Заголовки: Content-Type, Location у созданного ресурса, кеширование, CORS, если важно.
  3. Тело: значения полей, которые важны сценарию.
  4. Схема: типы, обязательные поля, отсутствие лишнего. Ловит тихие изменения контракта.
  5. Побочный эффект: после POST сделать GET и убедиться, что ресурс реально создан; после DELETE получить 404.
  6. Время ответа, если для эндпоинта есть требование.
def test_create_order(orders, user):
    r = orders.create(user_id=user.id, items=[{"sku": "A1", "qty": 2}])
    assert r.status_code == 201
    order = Order.model_validate(r.json())    # pydantic: схема и типы
    assert order.status == "new"
    assert orders.get(order.id).json()["items"][0]["qty"] == 2

Негативные и граничные проверки

Без токена (401), с чужим токеном (403), несуществующий id (404), невалидное тело (400 или 422 с понятной ошибкой), граничные значения длины и чисел, повторный запрос. Хорошее правило: на каждый позитивный тест эндпоинта несколько негативных, их удобно параметризовать.

Идемпотентность

GET, PUT, DELETE по спецификации HTTP идемпотентны: повтор не меняет результат на сервере. POST нет. Для платежей часто вводят заголовок идемпотентности (Idempotence-Key в ЮKassa, Idempotency-Key у многих других): повтор с тем же ключом не создаёт второй платёж. Это обязательный тест для платёжного API.

Тестовые данные и изоляция

Каждый тест создаёт свои сущности через API и удаляет их в teardown фикстуры. Уникальность обеспечивают суффиксами (uuid4().hex[:8]), чтобы параллельный запуск не сталкивался. Поля вроде created_at и id в сравнениях игнорируют или проверяют по формату.

Контрактные тесты

В микросервисах важно, что потребитель и поставщик одинаково понимают API. Consumer-driven contracts (Pact): потребитель описывает ожидания в контракте, поставщик в своём CI проверяет, что им соответствует. Ломающее изменение видно до деплоя, без общего стенда. Альтернатива попроще: проверка ответов по OpenAPI-схеме.

Частые ошибки

  • Проверять только статус 200.
  • Собирать запросы в тестах вручную, копируя заголовки.
  • Зависеть от данных, созданных руками на стенде.
  • Сравнивать весь ответ целиком вместе с id и временем.
  • Не логировать запрос и ответ: упавший тест в CI невозможно разобрать.

Что спросят на собесе

  • Что вы проверяете в ответе API, кроме статуса?
  • Как устроен ваш API-фреймворк: клиенты, модели, фикстуры?
  • Как проверяете схему ответа?
  • Что такое идемпотентность и как её протестировать?
  • Что такое контрактное тестирование?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.