`).\n\n* **Неверная авторизация/аутентификация:**\n * Отсутствие токена.\n * Просроченный/невалидный токен.\n * Недостаточно прав (попытка изменить чужой ресурс).\n\n* **Неверные параметры пути и запроса:**\n * Несуществующий ID в path (`/users/999999`).\n * Невалидные query-параметры (`/items?limit=-5`).\n\n* **Конфликты и бизнес-логика:**\n * Попытка создать дубликат (пользователь с тем же email).\n * Нарушение бизнес-правила (попытка отменить несуществующий заказ).\n\n**Ожидаемый результат для негативных тестов — четкая, понятная ошибка (чаще `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `409 Conflict`) с информативным телом.** Например:\n```json\n{\n \"error\": \"Validation failed\",\n \"details\": [\"Field 'email' must be a valid email address\"]\n}\n```\n\n### **Тестирование граничных значений (Boundary Value Analysis)**\nПрименяется к числовым полям и ограничениям длины.\n* Если `age` от 18 до 100, тестируем: 17, 18, 19, 99, 100, 101.\n* Если `name` макс. 50 символов, тестируем: 49, 50, 51 символ.\n\n### **Тестирование безопасности (Security)**\n* **Чувствительные данные:** Убедиться, что в ответах нет паролей, токенов, внутренних ID.\n* **Rate Limiting:** Проверить, что нельзя отправить 1000 запросов в секунду.\n* **Базовая проверка на инъекции,** как упоминалось выше.\n\n### **Тестирование производительности (Performance)**\n* **Время отклика** под нагрузкой (среднее, 95-й перцентиль).\n* Проверка, что медленные запросы (с большим количеством данных, сложной логикой) не превышают допустимый таймаут.\n\n## **3. Инструменты и практические шаги**\n\nЯ предпочитаю использовать **Postman** или **Charles** для первоначального ручного исследования, а затем автоматизировать в **Python (pytest + requests)** или **Java (REST Assured)**.\n\n**Пример базового автоматизированного теста на Python (pytest):**\n\n```python\nimport pytest\nimport requests\n\nBASE_URL = \"https://api.example.com/v1\"\nAUTH_TOKEN = \"your_valid_token_here\" # На практике берётся из конфига/фикстуры\n\ndef test_get_user_by_id_positive():\n \"\"\"Позитивный тест на получение пользователя по ID.\"\"\"\n user_id = 123\n headers = {\"Authorization\": f\"Bearer {AUTH_TOKEN}\"}\n\n response = requests.get(f\"{BASE_URL}/users/{user_id}\", headers=headers)\n\n assert response.status_code == 200\n user_data = response.json()\n assert user_data[\"id\"] == user_id\n assert \"name\" in user_data\n assert \"email\" in user_data\n # Можно добавить проверку по JSON-схеме (jsonschema library)\n\ndef test_create_user_negative_invalid_email():\n \"\"\"Негативный тест: создание пользователя с невалидным email.\"\"\"\n headers = {\"Authorization\": f\"Bearer {AUTH_TOKEN}\", \"Content-Type\": \"application/json\"}\n payload = {\n \"name\": \"Test User\",\n \"email\": \"not-an-email\", # Невалидный формат\n \"age\": 25\n }\n\n response = requests.post(f\"{BASE_URL}/users\", json=payload, headers=headers)\n\n # Ожидаем ошибку валидации\n assert response.status_code == 400\n error_data = response.json()\n assert \"error\" in error_data\n assert \"email\" in error_data.get(\"details\", \"\").lower()\n```\n\n## **4. Чек-лист для тестирования ручки (POST /ресурс)**\n\n* [ ] **Позитивный сценарий:** Отправка полного валидного тела → `201 Created`, ресурс создан.\n* [ ] **Минимальный набор:** Отправка только обязательных полей → `201 Created`.\n* [ ] **Ошибка валидации:** Пропуск обязательного поля → `400 Bad Request` с описанием.\n* [ ] **Ошибка валидации:** Неверный тип/формат данных → `400 Bad Request`.\n* [ ] **Ошибка аутентификации:** Запрос без токена/с невалидным токеном → `401 Unauthorized`.\n* [ ] **Ошибка авторизации:** Запрос с токеном, но без нужных прав → `403 Forbidden`.\n* [ ] **Конфликт:** Попытка создать дубликат (по уникальному полю) → `409 Conflict`.\n* [ ] **Неверный Content-Type:** Отправка, например, `text/plain` вместо `application/json` → `415 Unsupported Media Type`.\n* [ ] **Слишком большое тело запроса** → `413 Payload Too Large`.\n* [ ] **Инъекции:** Проверка строковых полей на SQL/HTML-инъекции (ожидается `400` или санитизация).\n* [ ] **Граничные значения:** Проверка числовых полей и полей длины.\n\n**Итог:** Тестирование ручки — это не только \"отправил-получил\". Это систематическая проверка **функциональности**, **надежности**, **безопасности** и **удобства использования (читаемость ошибок)** API. Всегда думайте не только о том, *что* должно работать, но и о том, *как* система должна *грамотно* ломаться.","dateCreated":"2026-04-05T17:34:18.213093","upvoteCount":0,"author":{"@type":"Person","name":"deepseek-v3.2"}}}}
← Назад к вопросам

Как протестировать ручку

1.0 Junior🔥 141 комментариев
#Техники тест-дизайна#Теория тестирования

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

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

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

Отличный и очень практичный вопрос. Тестирование REST API (или "ручки", endpoint) — одна из ключевых задач QA-инженера. Подход должен быть комплексным и охватывать не только "счастливый путь". Вот мой детальный разбор.

1. Подготовка и анализ

Прежде чем писать тесты, необходимо понять, что мы тестируем.

  • Изучи документацию (Swagger/OpenAPI). Уясни:
    *   **Цель ручки:** что она делает (GET, POST, PUT, DELETE, PATCH)?
    *   **Параметры запроса:** path-параметры (`/users/{id}`), query-параметры (`?page=1&limit=10`), тело запроса (body).
    *   **Типы данных и ограничения:** строки, числа, обязательные/необязательные поля, форматы (email, date), минимальные/максимальные значения.
    *   **Заголовки (headers):** `Authorization`, `Content-Type`, `Accept`.
    *   **Ожидаемые ответы:** коды статусов (200, 201, 400, 404, 500), структура и схема тела успешного ответа и ошибок.

  • Определите граничные условия и бизнес-логику. Понимание контекста — половина успеха. Например, для ручки создания заказа: "пользователь должен быть авторизован", "товар должен быть в наличии", "сумма не может быть отрицательной".

2. Основные категории тестирования

Тестирование можно разбить на несколько уровней. Я всегда начинаю с позитивных сценариев, чтобы убедиться, что базовый функционал работает.

Позитивное тестирование (Happy Path)

Проверяем, что ручка корректно работает при валидных данных.

  • Создание (POST): Отправляем полный валидный набор данных, проверяем статус 201 Created или 200 OK, тело ответа на соответствие схеме и корректность сохраненных данных (через БД или GET-запрос).
  • Получение (GET): Запрашиваем существующий ресурс, проверяем 200 OK и полное соответствие данных.
  • Обновление (PUT/PATCH): Меняем данные, проверяем 200 OK и факт обновления.
  • Удаление (DELETE): Удаляем, проверяем 200 OK или 204 No Content, и что ресурс больше нельзя получить (404 Not Found).

Негативное тестирование (Negative Testing)

Это самая важная и объемная часть. Цель — проверить, как система обрабатывает невалидные, неожиданные или вредоносные данные. Проверяем валидацию и обработку ошибок.

  • Невалидные данные:
    *   Обязательные поля: пропущены, `null`, пустая строка.
    *   Неверные типы: строка вместо числа (`"abc"` вместо `123`), массив вместо объекта.
    *   Нарушение формата: `email` без `@`, дата в неверном формате.
    *   Нарушение ограничений: отрицательный возраст, строка длиннее максимума, число вне диапазона.
    *   SQL-инъекции, XSS в строковых полях (например, `<script>alert(1)</script>`).

  • Неверная авторизация/аутентификация:
    *   Отсутствие токена.
    *   Просроченный/невалидный токен.
    *   Недостаточно прав (попытка изменить чужой ресурс).

  • Неверные параметры пути и запроса:
    *   Несуществующий ID в path (`/users/999999`).
    *   Невалидные query-параметры (`/items?limit=-5`).

  • Конфликты и бизнес-логика:
    *   Попытка создать дубликат (пользователь с тем же email).
    *   Нарушение бизнес-правила (попытка отменить несуществующий заказ).

Ожидаемый результат для негативных тестов — четкая, понятная ошибка (чаще 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict) с информативным телом. Например:

{
  "error": "Validation failed",
  "details": ["Field 'email' must be a valid email address"]
}

Тестирование граничных значений (Boundary Value Analysis)

Применяется к числовым полям и ограничениям длины.

  • Если age от 18 до 100, тестируем: 17, 18, 19, 99, 100, 101.
  • Если name макс. 50 символов, тестируем: 49, 50, 51 символ.

Тестирование безопасности (Security)

  • Чувствительные данные: Убедиться, что в ответах нет паролей, токенов, внутренних ID.
  • Rate Limiting: Проверить, что нельзя отправить 1000 запросов в секунду.
  • Базовая проверка на инъекции, как упоминалось выше.

Тестирование производительности (Performance)

  • Время отклика под нагрузкой (среднее, 95-й перцентиль).
  • Проверка, что медленные запросы (с большим количеством данных, сложной логикой) не превышают допустимый таймаут.

3. Инструменты и практические шаги

Я предпочитаю использовать Postman или Charles для первоначального ручного исследования, а затем автоматизировать в Python (pytest + requests) или Java (REST Assured).

Пример базового автоматизированного теста на Python (pytest):

import pytest
import requests

BASE_URL = "https://api.example.com/v1"
AUTH_TOKEN = "your_valid_token_here"  # На практике берётся из конфига/фикстуры

def test_get_user_by_id_positive():
    """Позитивный тест на получение пользователя по ID."""
    user_id = 123
    headers = {"Authorization": f"Bearer {AUTH_TOKEN}"}

    response = requests.get(f"{BASE_URL}/users/{user_id}", headers=headers)

    assert response.status_code == 200
    user_data = response.json()
    assert user_data["id"] == user_id
    assert "name" in user_data
    assert "email" in user_data
    # Можно добавить проверку по JSON-схеме (jsonschema library)

def test_create_user_negative_invalid_email():
    """Негативный тест: создание пользователя с невалидным email."""
    headers = {"Authorization": f"Bearer {AUTH_TOKEN}", "Content-Type": "application/json"}
    payload = {
        "name": "Test User",
        "email": "not-an-email",  # Невалидный формат
        "age": 25
    }

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

    # Ожидаем ошибку валидации
    assert response.status_code == 400
    error_data = response.json()
    assert "error" in error_data
    assert "email" in error_data.get("details", "").lower()

4. Чек-лист для тестирования ручки (POST /ресурс)

  • Позитивный сценарий: Отправка полного валидного тела → 201 Created, ресурс создан.
  • Минимальный набор: Отправка только обязательных полей → 201 Created.
  • Ошибка валидации: Пропуск обязательного поля → 400 Bad Request с описанием.
  • Ошибка валидации: Неверный тип/формат данных → 400 Bad Request.
  • Ошибка аутентификации: Запрос без токена/с невалидным токеном → 401 Unauthorized.
  • Ошибка авторизации: Запрос с токеном, но без нужных прав → 403 Forbidden.
  • Конфликт: Попытка создать дубликат (по уникальному полю) → 409 Conflict.
  • Неверный Content-Type: Отправка, например, text/plain вместо application/json415 Unsupported Media Type.
  • Слишком большое тело запроса413 Payload Too Large.
  • Инъекции: Проверка строковых полей на SQL/HTML-инъекции (ожидается 400 или санитизация).
  • Граничные значения: Проверка числовых полей и полей длины.

Итог: Тестирование ручки — это не только "отправил-получил". Это систематическая проверка функциональности, надежности, безопасности и удобства использования (читаемость ошибок) API. Всегда думайте не только о том, что должно работать, но и о том, как система должна грамотно ломаться.

Как протестировать ручку | PrepBro