← Назад к вопросам

Приведи пример тестирования PATCH

1.0 Junior🔥 161 комментариев
#Тестирование API

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Тестирование PATCH-запросов: подход и практический пример

PATCH — это HTTP-метод для частичного обновления ресурса. В отличие от PUT, который заменяет ресурс целиком, PATCH позволяет изменять только указанные поля, что делает его более эффективным и безопасным для больших объектов. Тестирование PATCH требует особого внимания, так как связано с проверкой частичных изменений, валидации и обработки граничных случаев.

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

При тестировании PATCH-эндпоинтов я проверяю следующие сценарии:

  • Позитивное тестирование:
    *   Обновление одного поля.
    *   Обновление нескольких полей одновременно.
    *   Обновление с корректными типами данных (строка, число, булево значение).
    *   Проверка, что неизменяемые поля (например, `id`, `createdAt`) остались прежними.
    *   Корректный HTTP-статус ответа (обычно `200 OK` или `204 No Content`).

  • Негативное тестирование и валидация:
    *   Отправка некорректного JSON.
    *   Попытка обновления несуществующим типом данных (например, строку вместо числа).
    *   Попытка обновления несуществующего поля (поведение зависит от API: должно либо игнорироваться, либо возвращать ошибку).
    *   Передача пустого тела запроса.
    *   Обновление несуществующего ресурса (должен возвращаться `404 Not Found`).
    *   Проверка валидации бизнес-логики (например, нельзя установить отрицательный возраст).

  • Тестирование безопасности и прав доступа:
    *   Вызов без авторизации (`401 Unauthorized`).
    *   Вызов с недостаточными правами (например, попытка изменить чужой профиль, `403 Forbidden`).
    *   Проверка на инъекции (например, SQL- или NoSQL-инъекции через строковые поля).

Практический пример: PATCH /api/users/{id}

Предположим, у нас есть API для управления пользователями. Эндпоинт PATCH /api/users/123 обновляет данные пользователя с id=123. Текущее состояние ресурса:

{
    "id": 123,
    "username": "old_user",
    "email": "old@example.com",
    "age": 25,
    "isActive": true
}

Тест-кейс 1: Успешное обновление нескольких полей

Шаги:

  1. Отправить PATCH-запрос с валидным токеном авторизации.
  2. Тело запроса:
    {
        "username": "new_username",
        "age": 26
    }
    
  3. Ожидаемый результат:
    *   Статус-код: `200 OK`.
    *   Тело ответа содержит обновлённый объект. Поля `username` и `age` изменены, а `email` и `isActive` остались прежними.
```json
{
    "id": 123,
    "username": "new_username",
    "email": "old@example.com",
    "age": 26,
    "isActive": true
}
```

4. Дополнительная проверка: Выполнить GET-запрос к тому же ресурсу, чтобы убедиться, что изменения действительно сохранились в базе данных.

Тест-кейс 2: Попытка обновления несуществующего поля (должно игнорироваться)

# Пример запроса с использованием curl
curl -X PATCH https://api.example.com/users/123 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"unknownField": "someValue", "age": 30}'

Ожидаемый результат: Поле unknownField проигнорировано, поле age обновлено до 30. В ответе не должно быть поля unknownField.

Тест-кейс 3: Обработка невалидных данных

Шаги:

  1. Отправить PATCH-запрос с некорректным значением для поля age (ожидается положительное число).
    {"age": -5}
    
  2. Ожидаемый результат:
    *   Статус-код: `400 Bad Request` или `422 Unprocessable Entity`.
    *   Тело ответа содержит сообщение об ошибке валидации.
```json
{
    "error": "Validation failed",
    "details": {"age": "Must be a positive number"}
}
```

Тест-кейс 4: Автоматизированный тест на Python (с использованием pytest и requests)

import pytest
import requests

BASE_URL = "https://api.example.com"
USER_ID = 123
AUTH_TOKEN = "valid_token_here"

def test_patch_user_partial_update():
    """Тест частичного обновления пользователя."""
    headers = {
        "Authorization": f"Bearer {AUTH_TOKEN}",
        "Content-Type": "application/json"
    }
    payload = {
        "email": "updated@example.com",
        "isActive": False
    }

    response = requests.patch(
        f"{BASE_URL}/users/{USER_ID}",
        json=payload,
        headers=headers
    )

    # Проверка статус-кода
    assert response.status_code == 200, f"Expected 200, got {response.status_code}"

    # Проверка обновлённых полей в ответе
    response_data = response.json()
    assert response_data["email"] == "updated@example.com"
    assert response_data["isActive"] is False

    # Проверка, что другие поля не изменились
    assert response_data["id"] == USER_ID
    assert "username" in response_data  # Поле осталось

def test_patch_user_nonexistent():
    """Тест обновления несуществующего пользователя."""
    headers = {"Authorization": f"Bearer {AUTH_TOKEN}"}
    response = requests.patch(
        f"{BASE_URL}/users/99999",
        json={"username": "test"},
        headers=headers
    )
    assert response.status_code == 404

def test_patch_user_unauthorized():
    """Тест обновления без авторизации."""
    response = requests.patch(
        f"{BASE_URL}/users/{USER_ID}",
        json={"username": "hacker"}
    )
    assert response.status_code == 401

Важные замечания по тестированию

  • Идемпотентность: PATCH не является идемпотентным по умолчанию (в отличие от PUT). Повторный запрос с тем же телом может привести к другому результату (например, инкремент счётчика). Это нужно явно тестировать, если такая логика заложена в API.
  • Формат запроса: Важно согласовать с разработчиками формат изменений. Это может быть JSON Merge Patch (простой JSON, как в примерах выше) или JSON Patch (RFC 6902), который использует массив операций (add, remove, replace, move, copy, test). Подход к тестированию будет разным.
  • Консистентность данных: После PATCH-запроса критически важно проверять не только ответ, но и актуальное состояние данных через GET, а также влияние изменений на связанные сущности.

Таким образом, тестирование PATCH — это комплексная задача, требующая проверки функциональности, валидации, безопасности и целостности данных. Автоматизация таких тестов, как показано в примере, является обязательной частью процесса обеспечения качества современного API.