🔗 Интеграционное тестирование

Что проверяет, подходы (снизу вверх, сверху вниз), контракты, моки и пример с БД.

Теория · Тестирование · #testing #integration

Что проверяет

Правильность взаимодействия модулей: вызовы между сервисами, обращение к БД, очередям, внешним API, форматы данных и обработка ошибок на стыках.

Подходы к порядку

Подход Суть
«Большой взрыв» всё вместе сразу (быстро, но трудно искать причину)
Снизу вверх сначала нижние модули, к ним добавляют верхние
Сверху вниз сначала верхние, нижние заменены заглушками
Сэндвич сочетание обоих
Инкрементальный по одному модулю за шаг

Что проверять на стыках

  • Формат запроса и ответа (поля, типы, обязательность).
  • Коды ошибок и таймауты.
  • Транзакции и откат при сбое.
  • Идемпотентность повторных вызовов.
  • Порядок и дублирование сообщений в очередях.
  • Права доступа между сервисами.
  • Совместимость версий API.

Примеры инструментов

Что тестируем Инструмент
REST API Postman, REST Assured, Supertest, pytest + requests
БД и сервисы в контейнерах Testcontainers
Контракты Pact (consumer-driven contract testing)
Сообщения тестовые брокеры, Embedded Kafka
Внешние сервисы WireMock, MockServer, Mountebank

Пример (Node.js, Supertest + реальная БД)

import request from 'supertest';
import { app } from './app';

it('создаёт пользователя и читает его из БД', async () => {
  const res = await request(app).post('/users').send({ email: 'a@x.ru' }).expect(201);
  const got = await request(app).get(`/users/${res.body.id}`).expect(200);
  expect(got.body.email).toBe('a@x.ru');
});

Пример (Java, Testcontainers)

@Testcontainers
class RepoIT {
    @Container
    static PostgreSQLContainer<?> db = new PostgreSQLContainer<>("postgres:16");
    // подключить репозиторий к db.getJdbcUrl() и проверить сохранение
}

Практики

  • Чистая БД на каждый тест или транзакция с откатом.
  • Фиксированные данные (фабрики, фикстуры), без зависимостей между тестами.
  • Внешние платные и нестабильные сервисы заменяйте заглушками, но ключевые контракты проверяйте отдельно.
  • Запускайте в CI на каждом изменении, но отдельным шагом от быстрых юнит-тестов.