Стратегия тестирования
Каноническая тестовая архитектура проекта. Обязательна для новых сервисов, модулей и коннекторов.
Пирамида тестирования
- Unit — основной объём покрытия, быстрые тесты рядом с кодом.
- Service / Integration — проверка адаптеров, wiring, транзакций, работы с БД, Kafka и compose-инфрой.
- Provider contract tests — проверка интеграций с внешними API на моковых ответах.
- E2E smoke — минимальный набор end-to-end сценариев на собранной среде.
Принцип: чем выше слой, тем меньше тестов и тем дороже их выполнение.
Unit-тесты
- Живут рядом с production-кодом (
*_test.goрядом с*.go). - Проверяют domain/app-логику изолированно.
- Используют только
mockery-сгенерированные моки для внутренних портов. - Не ходят в сеть, Kafka, PostgreSQL или файловую систему без явной причины.
- Должны быть быстрыми и запускаться на каждый коммит.
Правило по мокам
- Hand-written mocks/stubs/fakes для нового production-кода запрещены.
- Генерация моков фиксируется через
//go:generate mockery --name=.... - Библиотека ожиданий —
testify/mockили совместимый слой поверх сгенерированных моков.
Service / Integration тесты
Покрывают сценарии, где важно реальное взаимодействие нескольких частей системы:
- wiring модулей и DI composition root;
- SQL-модели, миграции и транзакции;
- Kafka publishers/consumers;
- observability adapters;
- взаимодействие с compose-инфраструктурой.
Правила:
- использовать реальные адаптеры или testcontainers/compose-backed среду, если это отражает production-поведение;
- не подменять критичные инфраструктурные адаптеры там, где тест проверяет именно их;
- запускать на каждом MR.
Provider contract тесты
Для каждого внешнего API-клиента обязателен отдельный контрактный слой.
Как устроены
- источник истины — зафиксированные HTTP-фикстуры из реальных или sandbox ответов поставщика;
- фикстуры хранятся в
testdata/contracts/<provider>/...; - тест поднимает моковый HTTP server (
httptest.Serverили эквивалент); - клиент ходит в этот сервер так же, как пошёл бы в production API;
- проверяются форма запроса, refresh auth, пагинация, retry/backoff, парсинг и маппинг ошибок.
Что нельзя
- нельзя делать live API-вызовы к поставщику в blocking MR pipeline;
- нельзя заменять contract tests unit-моками на уровне
http.Client; - нельзя хранить только “happy path” без ошибок 401/429/5xx и кейсов с грязным payload.
Допустимое дополнение
Scheduled/nightly smoke к provider sandbox допускается как отдельный неосновной контур.
E2E smoke
Нужен ограниченный набор сценариев:
- старт compose-среды;
- базовая готовность ключевых сервисов;
- один-два критичных пользовательских сценария;
- smoke на publish/consume цепочки.
E2E не должен быть главным местом регрессии. Его задача — поймать wiring/regression уровня среды.
Рекомендуемая раскладка тестов
core/<module>/
app/
service.go
service_test.go
mocks/
connectors/<provider>/
infra/integration/
client_contract_test.go
testdata/contracts/<provider>/
internal/tests/
integration/
e2e/Ожидания CI
- Unit, service/integration и provider contract тесты — обязательная часть MR pipeline.
- E2E smoke — по default branch, release pipeline или manual/scheduled job.
- Любое изменение контракта внешнего API требует обновления фикстур и contract тестов.