В чем ключевые особенности тестирования HTTP-метода PATCH в REST API?

«В чем ключевые особенности тестирования HTTP-метода PATCH в REST API?» — вопрос из категории API тестирование, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

PATCH используется для частичного обновления ресурса. В отличие от PUT, который требует отправки полного представления ресурса, PATCH применяет изменения только к указанным полям.

Ключевые аспекты для тестирования:

  1. Семантика частичного обновления:

    • Проверка, что обновляются только переданные в запросе поля. Остальные поля ресурса должны остаться неизменными.
    • Пример запроса, обновляющего только email:

      PATCH /api/v1/users/123 HTTP/1.1
      Content-Type: application/json-patch+json
      
      [
        { "op": "replace", "path": "/email", "value": "new.email@example.com" }
      ]
  2. Форматы тела запроса: API может поддерживать разные форматы (JSON Patch, JSON Merge Patch). Необходимо тестировать каждый из них.

  3. Валидация и обработка ошибок:

    • 400 Bad Request: При невалидном формате запроса (некорректный JSON), несуществующих полях (в зависимости от спецификации) или нарушении бизнес-правил.
    • 404 Not Found: Если ресурс с указанным ID не существует.
    • 409 Conflict: При попытке обновления, ведущей к конфликту (например, установка неуникального значения).
    • 422 Unprocessable Entity: Для ошибок валидации данных (некорректный формат email).
  4. Идемпотентность: PATCH не всегда идемпотентен. Это зависит от используемого формата и логики операции. JSON Patch с операцией "replace" — идемпотентен, а "add" — нет. Это важно для логики повторных запросов.

  5. Оптимистичная блокировка: Проверка работы с заголовками If-Match (на основе ETag) для предотвращения "состояния гонки" при конкурентных обновлениях.

  6. Edge Cases:

    • Отправка пустого тела запроса или массива операций.
    • Попытка обновления read-only полей (например, id, createdAt).
    • Обновление поля значением null (должно ли это очищать поле?).