Расскажите о вашем подходе к покрытию кода тестами. Какие метрики вы считаете хорошими?

Ответ

Главное — понимать, что покрытие тестами (code coverage) — это полезная метрика, но не самоцель. Высокий процент покрытия не гарантирует отсутствие багов, а лишь показывает, какая часть кода была выполнена во время тестов.

Наш подход строится на нескольких принципах:

  1. Дифференцированные цели. Мы не гонимся за одинаковым процентом для всего проекта:

    • Критически важная бизнес-логика, пакеты с алгоритмами: стремимся к 85-90%+.
    • Стандартный код (контроллеры, CRUD): достаточно 70-80%.
    • Код, который сложно тестировать (например, интеграции с UI): покрываем юнит-тестами по возможности, основной упор делаем на ручное или E2E-тестирование.
  2. Качество важнее количества. Один тест на пограничный случай (edge case) или обработку ошибки ценнее десяти тестов, проверяющих "счастливый путь" (happy path).

  3. Автоматизация в CI/CD. Проверка покрытия встроена в наш CI-пайплайн. Пул-реквест не может быть смержен, если покрытие нового или измененного кода падает ниже установленного порога (например, 80%).

    # Пример команды для проверки покрытия
    go test -coverprofile=coverage.out ./...
    go tool cover -func=coverage.out
    
    # Вывод может выглядеть так:
    # ok   project/pkg/utils   0.002s  coverage: 85.2% of statements
  4. Прагматичный подход к легаси. Мы не ставим задачу покрыть тестами весь старый код сразу. Но любое изменение или исправление бага в легаси-коде обязательно сопровождается написанием тестов для затрагиваемой логики.

Важное дополнение

Мы не стремимся к 100% покрытию, так как это часто экономически нецелесообразно (закон убывающей отдачи). Гораздо важнее иметь осмысленные интеграционные и E2E тесты, которые проверяют работу системы в целом, даже если они не влияют на метрику покрытия unit-тестами.