Как подходы unit-тестирования, интеграционного тестирования и тестирования на уровне системы дополняют друг друга: приведите пример набора тестов для REST API и объясните, какие баги каждый уровень выявит
Кратко о дополняемости уровней: - Unit-тесты: проверяют малые изолированные компоненты (функции, сервисы, валидаторы) быстро и детерминированно — ловят логические ошибки, неверные граничные условия, регрессии в реализации. - Интеграционные тесты: проверяют взаимодействие между компонентами (контроллер ↔ сервис ↔ репозиторий, внешние библиотеки, драйвер БД) — ловят ошибки интеграции, некорректную сериализацию/десериализацию, ошибки в контракте между модулями. - Системные (end-to-end) тесты: тестируют весь стек приложения в условиях, близких к проду (HTTP, auth, БД, очереди) — ловят ошибки маршрутизации, конфигурации, проблемы производительности, кросс-слойные сценарии и UX-проблемы. Пример: REST API для ресурса /users с эндпоинтами POST /users, GET /users/{id}, PUT /users/{id}, DELETE /users/{id} и GET /users?active=true. 1) Unit-тесты (изолировано, быстро) - Тесты валидатора входных данных: - Ввод: некорректный email -> ожидание ошибки валидации. - Границы: поле name длиной "0""0""0", "256""256""256" символов. - Тесты бизнес-логики (например, функция создания пользователя): - При дубликате email — бросается специфичная ошибка. - Пароль хэшируется вызовом хеш-функции (мокаем функцию хеширования и проверяем вызовы). - Тесты контроллера (мокаем сервис): - При успешном создании возвращает статус "201""201""201" и тело с id. - При ошибке в сервисе возвращает корректный статус/сообщение. Какие баги выявят unit-тесты: - Неправильная валидация формата email или длины полей. - Ошибки в алгоритмах/условных операциях (например, неверный подсчёт прав доступа). - Пропущенные вызовы сторонних функций (хеширование, валидация) — при моке видно отсутствие вызова. 2) Интеграционные тесты (несколько компонентов вместе, реальная/интегрированная БД или тестовая) - Тесты контроллер ↔ сервис ↔ репозиторий: - POST /users с корректными данными — запись в тестовую БД, возвращает "201""201""201", последующий GET /users/{id} возвращает те же данные. - POST /users с дублирующим email — сервис возвращает ошибку, репозиторий генерирует конфликт (тест проверяет обработку ошибки БД). - Тесты serialization/deserialization: - Сохранение и чтение даты/форматов (например, дата регистрации) — сохраняется и читается без смещения. - Тесты интеграции с внешним сервисом (например, отправка welcome-письма) — мока внешнего API, проверка, что событие отправлено после сохранения. Какие баги выявят интеграционные тесты: - Неправильная обработка исключений от БД (например, уникальность не перехватывается → 500 вместо "400""400""400"/"409""409""409"). - Некорректные SQL/ORM-маппинги (поле не сохраняется или сохраняется в неверном типе). - Несовпадение контрактов между слоями (например, контроллер ожидает поле id как integer, а репозиторий возвращает string). - Ошибки в преобразовании даты/времени, проблемные кодировки. 3) Системные (E2E) тесты (через HTTP, с реальной конфигурацией) - Позитивные сценарии: - Полный поток: POST /users → авторизация (если требуется) → GET /users/{id} → PUT /users/{id} → DELETE → проверка отсутствия. - Негативные и граничные сценарии: - Неверный JWT токен — запросы получают "401""401""401". - Массовые запросы (нагрузочный тест небольшого масштаба) — проверка времени ответа и устойчивости. - Тесты CORS, маршрутизации, заголовков и cookie. - Тесты миграций/развёртывания: - Запуск приложения с текущей БД миграциями — проверка, что эндпоинты работают после миграции. Какие баги выявят системные тесты: - Проблемы конфигурации окружения (неподключённый сервис отправки почты, неверные переменные окружения). - Ошибки аутентификации/авторизации в реальной цепочке (gateway → сервис). - Проблемы маршрутизации, CORS, TLS/HTTPS, reverse-proxy. - Непредвиденные взаимодействия между фичами (например, middleware, который блокирует определённые заголовки и ломает авторизацию). - Производительность и устойчивость при одновременных запросах, утечки ресурсов. Короткие рекомендации по набору тестов: - Unit: покрыть все валидации, ветвления и критичные функции (быстро, моки). - Integration: покрыть основные CRUD-потоки с реальной или тестовой БД и ключевыми интеграциями. - System/E2E: несколько полных потоков (+ негативные и auth/permission сценарии), плюс один нагрузочный и smoke-тест после деплоя. Итог: уровни дополняют друг друга — unit ловит внутреннюю логику, интеграционные — контракт и взаимодействие модулей, системные — конфигурацию и поведение приложения в продоподобной среде.
- Unit-тесты: проверяют малые изолированные компоненты (функции, сервисы, валидаторы) быстро и детерминированно — ловят логические ошибки, неверные граничные условия, регрессии в реализации.
- Интеграционные тесты: проверяют взаимодействие между компонентами (контроллер ↔ сервис ↔ репозиторий, внешние библиотеки, драйвер БД) — ловят ошибки интеграции, некорректную сериализацию/десериализацию, ошибки в контракте между модулями.
- Системные (end-to-end) тесты: тестируют весь стек приложения в условиях, близких к проду (HTTP, auth, БД, очереди) — ловят ошибки маршрутизации, конфигурации, проблемы производительности, кросс-слойные сценарии и UX-проблемы.
Пример: REST API для ресурса /users с эндпоинтами POST /users, GET /users/{id}, PUT /users/{id}, DELETE /users/{id} и GET /users?active=true.
1) Unit-тесты (изолировано, быстро)
- Тесты валидатора входных данных:
- Ввод: некорректный email -> ожидание ошибки валидации.
- Границы: поле name длиной "0""0""0", "256""256""256" символов.
- Тесты бизнес-логики (например, функция создания пользователя):
- При дубликате email — бросается специфичная ошибка.
- Пароль хэшируется вызовом хеш-функции (мокаем функцию хеширования и проверяем вызовы).
- Тесты контроллера (мокаем сервис):
- При успешном создании возвращает статус "201""201""201" и тело с id.
- При ошибке в сервисе возвращает корректный статус/сообщение.
Какие баги выявят unit-тесты:
- Неправильная валидация формата email или длины полей.
- Ошибки в алгоритмах/условных операциях (например, неверный подсчёт прав доступа).
- Пропущенные вызовы сторонних функций (хеширование, валидация) — при моке видно отсутствие вызова.
2) Интеграционные тесты (несколько компонентов вместе, реальная/интегрированная БД или тестовая)
- Тесты контроллер ↔ сервис ↔ репозиторий:
- POST /users с корректными данными — запись в тестовую БД, возвращает "201""201""201", последующий GET /users/{id} возвращает те же данные.
- POST /users с дублирующим email — сервис возвращает ошибку, репозиторий генерирует конфликт (тест проверяет обработку ошибки БД).
- Тесты serialization/deserialization:
- Сохранение и чтение даты/форматов (например, дата регистрации) — сохраняется и читается без смещения.
- Тесты интеграции с внешним сервисом (например, отправка welcome-письма) — мока внешнего API, проверка, что событие отправлено после сохранения.
Какие баги выявят интеграционные тесты:
- Неправильная обработка исключений от БД (например, уникальность не перехватывается → 500 вместо "400""400""400"/"409""409""409").
- Некорректные SQL/ORM-маппинги (поле не сохраняется или сохраняется в неверном типе).
- Несовпадение контрактов между слоями (например, контроллер ожидает поле id как integer, а репозиторий возвращает string).
- Ошибки в преобразовании даты/времени, проблемные кодировки.
3) Системные (E2E) тесты (через HTTP, с реальной конфигурацией)
- Позитивные сценарии:
- Полный поток: POST /users → авторизация (если требуется) → GET /users/{id} → PUT /users/{id} → DELETE → проверка отсутствия.
- Негативные и граничные сценарии:
- Неверный JWT токен — запросы получают "401""401""401".
- Массовые запросы (нагрузочный тест небольшого масштаба) — проверка времени ответа и устойчивости.
- Тесты CORS, маршрутизации, заголовков и cookie.
- Тесты миграций/развёртывания:
- Запуск приложения с текущей БД миграциями — проверка, что эндпоинты работают после миграции.
Какие баги выявят системные тесты:
- Проблемы конфигурации окружения (неподключённый сервис отправки почты, неверные переменные окружения).
- Ошибки аутентификации/авторизации в реальной цепочке (gateway → сервис).
- Проблемы маршрутизации, CORS, TLS/HTTPS, reverse-proxy.
- Непредвиденные взаимодействия между фичами (например, middleware, который блокирует определённые заголовки и ломает авторизацию).
- Производительность и устойчивость при одновременных запросах, утечки ресурсов.
Короткие рекомендации по набору тестов:
- Unit: покрыть все валидации, ветвления и критичные функции (быстро, моки).
- Integration: покрыть основные CRUD-потоки с реальной или тестовой БД и ключевыми интеграциями.
- System/E2E: несколько полных потоков (+ негативные и auth/permission сценарии), плюс один нагрузочный и smoke-тест после деплоя.
Итог: уровни дополняют друг друга — unit ловит внутреннюю логику, интеграционные — контракт и взаимодействие модулей, системные — конфигурацию и поведение приложения в продоподобной среде.