Что такое CRUD

CRUD означает Create, Read, Update, Delete — четыре базовые операции для постоянного хранения данных. Практически каждый API endpoint соответствует одной из этих операций:

CRUDHTTP-методПримерТипичный статус
CreatePOSTPOST /users201 Created
ReadGETGET /users/42200 OK
UpdatePUT / PATCHPUT /users/42200 OK
DeleteDELETEDELETE /users/42204 No Content

Систематическое тестирование CRUD-операций гарантирует, что API корректно обрабатывает весь жизненный цикл ресурса — от создания до удаления.

Тестирование Create (POST)

Тесты позитивного сценария

POST /api/users
Content-Type: application/json

{
  "name": "Alice Johnson",
  "email": "alice@example.com",
  "role": "developer"
}

Проверить:

  • Статус ответа 201 Created
  • Тело ответа содержит созданный ресурс со сгенерированным id
  • Все отправленные поля присутствуют в ответе
  • Серверные поля существуют (id, createdAt, updatedAt)
  • Заголовок Location указывает на URL нового ресурса
  • Получение ресурса через GET возвращает те же данные

Тесты валидации

СценарийОжидание
Отсутствует обязательное поле (name)400 с понятным сообщением об ошибке
Пустое обязательное поле ("")400 с ошибкой валидации
Невалидный формат email400/422 с ошибкой формата
Строка вместо числа400 с ошибкой типа
Значение превышает максимальную длину400 с ошибкой длины
Лишние неизвестные поляИгнорируются или 400 (зависит от дизайна)

Тесты уникальности

СценарийОжидание
Дублирующийся email409 Conflict
Дублирующееся имя (если уникальное)409 Conflict
Чувствительность к регистру (alice@test.com vs Alice@test.com)Зависит от дизайна API

Тесты границ

  • Максимальные длины полей (255 символов для имени и т.д.)
  • Специальные символы: Unicode, эмодзи, HTML-теги, строки SQL injection
  • Минимальные значения: пустые массивы, нулевые количества
  • Максимальный размер payload

Тестирование Read (GET)

Отдельный ресурс

GET /api/users/42

Проверить:

  • Возвращает 200 OK с полными данными пользователя
  • Все ожидаемые поля присутствуют
  • Типы данных корректны (число для id, строка для имени)
  • Чувствительные поля исключены (пароль, внутренние ID)

Коллекция (список)

GET /api/users?page=1&limit=20&sort=name&order=asc

Проверить:

  • Возвращает массив ресурсов
  • Метаданные пагинации присутствуют (total, page, limit, pages)
  • Сортировка работает корректно
  • Фильтрация возвращает только подходящие ресурсы
  • Пагинация по умолчанию применяется при отсутствии параметров

Граничные случаи

СценарийОжидание
Несуществующий ID (GET /users/99999)404 Not Found
Невалидный формат ID (GET /users/abc)400 или 404
Отрицательный ID (GET /users/-1)400 или 404
Страница за пределами результатов (?page=9999)200 с пустым массивом
Очень большой limit (?limit=100000)Ограничен максимумом или 400

Тестирование Update (PUT / PATCH)

PUT — Полная замена

PUT /api/users/42
Content-Type: application/json

{
  "name": "Alice Smith",
  "email": "alice.smith@example.com",
  "role": "senior-developer"
}

Проверить:

  • Все поля заменены новыми значениями
  • Пропущенные опциональные поля сброшены к значениям по умолчанию или удалены
  • Временная метка updatedAt изменилась
  • id и createdAt остались прежними
  • GET после PUT возвращает обновлённые данные

PATCH — Частичное обновление

PATCH /api/users/42
Content-Type: application/json

{
  "role": "senior-developer"
}

Проверить:

  • Изменилось только указанное поле
  • Все остальные поля остались без изменений
  • Временная метка updatedAt изменилась

Граничные случаи обновления

СценарийОжидание
Обновление несуществующего ресурса404 Not Found
Обновление с невалидными данными400 с ошибкой валидации
Обновление полей только для чтения (id, createdAt)400 или поля игнорируются
Конкурентные обновления (два PUT одновременно)Последняя запись побеждает или 409
Обновление до дублирующегося уникального значения409 Conflict

Тестирование Delete (DELETE)

Стандартное удаление

DELETE /api/users/42

Проверить:

  • Возвращает 204 No Content (или 200 OK с подтверждением)
  • GET удалённого ресурса возвращает 404
  • Ресурс больше не появляется в endpoint-е списка
  • Связанные ресурсы обработаны корректно (каскад или защита от осиротевших записей)

Граничные случаи удаления

СценарийОжидание
Удаление несуществующего ресурса404 Not Found
Удаление уже удалённого ресурса404 Not Found
Удаление ресурса с зависимостями409 или каскадное удаление
Удаление без авторизации401/403

End-to-End тест CRUD-потока

Самый важный тест — полный жизненный цикл:

1. POST /users → Создать пользователя → Сохранить ID
2. GET /users/{id} → Проверить, что пользователь существует с правильными данными
3. GET /users → Проверить, что пользователь есть в списке
4. PUT /users/{id} → Обновить все поля
5. GET /users/{id} → Проверить применение обновления
6. PATCH /users/{id} → Частично обновить одно поле
7. GET /users/{id} → Проверить, что изменилось только это поле
8. DELETE /users/{id} → Удалить пользователя
9. GET /users/{id} → Проверить 404
10. GET /users → Проверить, что пользователя нет в списке

Этот поток тестирует персистентность, консистентность и очистку данных через весь жизненный цикл.

Связи данных

Когда ресурсы имеют связи (у пользователя много заказов), тестируйте:

  • Создание дочернего ресурса с валидным ID родителя
  • Создание дочернего ресурса с невалидным ID родителя (должно упасть)
  • Удаление родителя с существующими детьми (каскадное поведение)
  • Получение родителя включает/исключает детей как задокументировано
  • Обновление родителя не влияет на данные дочерних записей

Практическое упражнение

Используя JSONPlaceholder (https://jsonplaceholder.typicode.com):

  1. Полный CRUD-цикл: Создайте пост, прочитайте его, обновите через PUT, частично обновите через PATCH, удалите, проверьте удаление
  2. Тестирование валидации: Попробуйте создать пост с отсутствующими полями, неправильными типами, пустыми значениями
  3. Тестирование связей: Создайте пост, затем создайте комментарии для этого поста. Что произойдёт при удалении поста?
  4. Тестирование списков: Протестируйте пагинацию, фильтрацию по userId и проверьте структуру ответа для GET /posts

Ключевые выводы

  • CRUD-операции — основа тестирования API, каждый ресурс проходит через создание, чтение, обновление, удаление
  • Всегда проверяйте персистентность данных, следуя за POST запросом GET для подтверждения реального существования ресурса
  • Тестируйте и PUT (полная замена), и PATCH (частичное обновление), чтобы убедиться в их различном поведении
  • End-to-end тесты CRUD-потока обнаруживают интеграционные баги, которые тесты отдельных операций могут пропустить
  • Не забывайте о граничных случаях: несуществующие ресурсы, дубликаты, каскадные удаления и конкурентные обновления