Что такое CRUD
CRUD означает Create, Read, Update, Delete — четыре базовые операции для постоянного хранения данных. Практически каждый API endpoint соответствует одной из этих операций:
| CRUD | HTTP-метод | Пример | Типичный статус |
|---|---|---|---|
| Create | POST | POST /users | 201 Created |
| Read | GET | GET /users/42 | 200 OK |
| Update | PUT / PATCH | PUT /users/42 | 200 OK |
| Delete | DELETE | DELETE /users/42 | 204 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 с ошибкой валидации |
| Невалидный формат email | 400/422 с ошибкой формата |
| Строка вместо числа | 400 с ошибкой типа |
| Значение превышает максимальную длину | 400 с ошибкой длины |
| Лишние неизвестные поля | Игнорируются или 400 (зависит от дизайна) |
Тесты уникальности
| Сценарий | Ожидание |
|---|---|
| Дублирующийся email | 409 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):
- Полный CRUD-цикл: Создайте пост, прочитайте его, обновите через PUT, частично обновите через PATCH, удалите, проверьте удаление
- Тестирование валидации: Попробуйте создать пост с отсутствующими полями, неправильными типами, пустыми значениями
- Тестирование связей: Создайте пост, затем создайте комментарии для этого поста. Что произойдёт при удалении поста?
- Тестирование списков: Протестируйте пагинацию, фильтрацию по userId и проверьте структуру ответа для GET /posts
Ключевые выводы
- CRUD-операции — основа тестирования API, каждый ресурс проходит через создание, чтение, обновление, удаление
- Всегда проверяйте персистентность данных, следуя за POST запросом GET для подтверждения реального существования ресурса
- Тестируйте и PUT (полная замена), и PATCH (частичное обновление), чтобы убедиться в их различном поведении
- End-to-end тесты CRUD-потока обнаруживают интеграционные баги, которые тесты отдельных операций могут пропустить
- Не забывайте о граничных случаях: несуществующие ресурсы, дубликаты, каскадные удаления и конкурентные обновления