Если бы QA-процессы были сериалом, то юнит-тесты были бы первой серией: короткие, местами скучные, но дают понять, кто есть кто. А вот интеграционные тесты — это середина сезона. Вроде бы уже разобрались с персонажами, но именно сейчас начинает закручиваться сюжет.
Интеграционное тестирование — это проверка взаимодействия между модулями, сервисами, компонентами, библиотеками и всем тем, что разработчики уверенно называют «инкапсулированным» и «изолированным». Суть в том, чтобы понять: не только работает ли каждый из них по отдельности, но и работают ли они вместе.
Допустим, у нас есть три модуля:
- фронт: форма логина;
- бэк: сервис авторизации;
- база: хранит пользователей и токены.
Каждый из них отдельно может быть идеально покрыт юнитами. Но когда фронт отправляет логин и пароль, бэк должен это распарсить, сходить в базу, получить токен и отдать его обратно. И вот тут начинается реальность. Не «идеальная модель мира», а тот самый момент, где JSON окажется в другом регистре, токен в другом формате, а база внезапно не вернёт ничего — потому что в миграции забыли поле is_active
.
Вот для этого и нужно интеграционное тестирование.
Юнит — это проверка логики одного блока. Например, функция validate_email()
работает как задумано. Интеграция — это когда validate_email()
используется внутри register_user()
, который потом вызывает send_confirmation_email()
, и ты проверяешь, что всё вместе работает.
Интеграция:
- проверяет цепочку действий,
- тестирует коммуникацию между сервисами и компонентами,
- выявляет ошибки «на стыке» (а именно они и валятся на проде чаще всего).
В интеграционном тестировании мы тестируем:
- Связь между модулями
- API вызывает нужные ручки
- фронт корректно обрабатывает ответ
- Обмен данными
- правильно ли сериализуются и десериализуются объекты
- нет ли багов при маппинге данных между слоями
- Логика между сервисами
- пользователь зарегался → письмо отправилось → запись появилась в БД
- Обработка ошибок
- если зависимый сервис упал, система не развалилась
Как писать интеграционные тесты?
Как и всё хорошее в жизни — с пониманием, зачем ты это делаешь.
1. Окружение
Нужна среда, максимально приближённая к боевой. Обычно это:
- docker-compose со всеми зависимостями (БД, кэш, сторонние сервисы);
- настроенная CI-сборка, в которой можно гонять интеграционные тесты отдельно от юнитов (они дольше и сложнее в поддержке);
- фейковые сервисы или моки, если реальных нет.
2. Инструменты
- На Python —
pytest
,requests
,docker-compose
,testcontainers
- На JS —
Jest
,Supertest
,msw
- На Java —
SpringBootTest
,Testcontainers
,WireMock
Главное — не пытаться всё мокать. Интеграция — это как раз чтобы проверить, как настоящие сервисы взаимодействуют.
3. Сценарии
Пиши не от интерфейса, а от процессов. Не «открываю страницу», а «пользователь логинится», «оплачивает подписку», «смотрит видео». Нам нужно проверить именно интеграцию, а не нажатие конкретной кнопки.
Каждый сценарий — это:
- начальные данные (юзер, товар, токен);
- действия (запросы, симуляции);
- ожидания (ответ, запись в БД, письмо ушло, пуш отправлен).
Проблемы, с которыми придется столкнуться:
- Сложно дебажить. Если тест падает, не всегда понятно, где именно сломалось: в логике, в окружении или в данных. Нужно писать хорошие логи и уметь воспроизводить руками.
- Хрупкие тесты. Если структура ответа поменялась — тест падает. Нужно отдельно изучать JSON-hell.
- Время выполнения. Интеграционные тесты всегда медленнее. Поэтому в CI/CD лучше отделять их от юнитов.
Чем интеграционный тест отличается от е2е теста? Интеграция — это внутри одной системы: API + БД, или два сервиса между собой; e2e — это когда мы симулируем действия конечного пользователя: от клика по кнопке до оплаты.
Например: запрос POST /payment
и проверка, что платёж создан и запись попала в базу — это интеграция. А вот открыть браузер, зайти в профиль, нажать «оплатить» и получить письмо — это e2e.
Интеграционные тесты — как регулярная проверка на СТО. Машина вроде едет, но если не посмотреть, как у неё дела с тормозами, сцеплением и коробкой, можно уехать далеко и дорого. Да, писать такие тесты дольше. Да, инфраструктура сложнее. Но с ними ты перестаёшь быть QA, который просто «нажал кнопку», и становишься QA, который видит, как работает продукт целиком. Если ты работаешь в проекте, где несколько сервисов, база, API, очередь, пуши, и всё это как-то взаимодействует — интеграционное тестирование тебе нужно. Даже если оно иногда неприятное, как вставать в бассейн в 7 утра. Но потом — работает.