← Назад к вопросам

Кто должен контролировать уровень покрытия автотестов

2.0 Middle🔥 71 комментариев
#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ответственность за контроль покрытия тестов

Покрытие тестами (test coverage) — это метрика качества кода. Вопрос в том, кто должен её отслеживать и контролировать.

Распределение ответственности

1. Разработчик (главная роль)

Разработчик обязан:

  • Писать тесты вместе с кодом (TDD подход)
  • Проверять локально, что покрытие >= 80%
  • Не коммитить код без тестов (code review партнера должен это поймать)
// До коммита: запустить локально
$ mvn clean test jacoco:report
$ cat target/site/jacoco/index.html

Почему на разработчике:

  • Только разработчик знает, какие case-ы критичны
  • Первая линия контроля — самый эффективный способ
  • Если оставить на конец — будет больно переделывать

2. Code Review (парный контроль)

При code review проверяем:

  • Все функции имеют тесты
  • Покрыты happy path и edge case-ы
  • Не снижается глобальное покрытие репо
  • Тесты скорые и надёжные (не flaky)
// Во время code review — не пропускаем такое
@RequestMapping("/users/{id}")
public User getUser(@PathVariable Long id) { // БЕЗ ТЕСТА?
    return repository.findById(id)...;
}

Code reviewer спрашивает:

  • "Где тесты для happy path (user exists)?"
  • "А если user не найден (404)?"
  • "Покрытие не упало?"

3. CI/CD Pipeline (автоматический контроль)

Pipeline должен:

  • Запустить mvn test и отклонить PR если tests fail
  • Проверить покрытие: jacoco:report
  • Вернуть ошибку если coverage < threshold
# .github/workflows/ci.yml
name: Tests
on: [pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
      - run: mvn clean test jacoco:report
      - run: |
          COVERAGE=$(mvn jacoco:report | grep "Total" | awk '{print $3}')
          if (( $(echo "$COVERAGE < 80" | bc -l) )); then
            echo "Coverage too low: $COVERAGE%"
            exit 1
          fi

Плюсы CI контроля:

  • Невозможно забыть — pipeline не даст merge
  • Метрики видны всем
  • История покрытия отслеживается

4. Lead/Архитектор (стратегический уровень)

Лид отвечает за:

  • Установление threshold покрытия для проекта (70%, 80%, 90%?)
  • Выбор инструмента (JaCoCo, Cobertura, PiTest)
  • Разбор случаев, когда нарушаются стандарты
  • Улучшение культуры тестирования в команде
// В pom.xml лид настраивает порог
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.10</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
                <goal>check</goal> <!-- ПРОВЕРКА ВО ВРЕМЯ BUILD -->
            </goals>
            <configuration>
                <rules>
                    <rule>
                        <element>PACKAGE</element>
                        <excludes>
                            <exclude>*Test</exclude>
                        </excludes>
                        <limits>
                            <limit>
                                <counter>LINE</counter>
                                <value>COVEREDRATIO</value>
                                <minimum>0.80</minimum> <!-- МИН 80% -->
                            </limit>
                        </limits>
                    </rule>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>

5. QA/Тестовая команда (интеграционные тесты)

Автоматизированные e2e тесты обычно не входят в coverage %, но они тоже важны:

// E2E Playwright тест
@Test
public void userCanCreateOrderAndCheckout() {
    page.navigate("http://localhost:3000");
    page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Create Order"))
        .click();
    page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Checkout"))
        .click();
    assertThat(page).hasURL("http://localhost:3000/order/success");
}

Правильный баланс

Unit Tests (JUnit + Mockito): 70-80% покрытия

  • Быстрые (мс)
  • Тестируют бизнес-логику
  • Разработчик пишет

Integration Tests: 10-20% покрытия

  • Медленнее (сек)
  • Тестируют БД, API, внешние сервисы
  • QA + разработчик пишут

E2E Tests: 5-10% покрытия

  • Медленные (несколько сек)
  • Критичные user journey-s
  • QA пишет
Тестовая пирамида:

      /\       E2E (5%)
     /  \      UI Интеграция (5%)
    /    \     Интеграция (20%)
   /      \    Unit Tests (70%)
  /________\

Практический пример: мой процесс

# 1. Пишу юнит тест (RED)
$ cat > UserServiceTest.java
@Test
public void findUserByIdReturnsUser() {
    User user = service.findById(1L);
    assertThat(user.getName()).isEqualTo("John");
}

# 2. Запускаю локально — падает
$ mvn test
# FAILED

# 3. Пишу код (GREEN)
@Service
public class UserService {
    public User findById(Long id) {
        return repository.findById(id).orElse(null);
    }
}

# 4. Запускаю тесты + покрытие
$ mvn clean test jacoco:report
# Coverage: 85% ✓

# 5. Code review — партнер проверяет
# - Тест покрывает edge case?
# - Покрытие не упало?
# - Тесты быстрые?

# 6. Merge в main
# CI pipeline перепроверит всё автоматически
$ git push origin feature/user-service

Частые ошибки

Ошибка 1: Тесты только на конец спринта

// НЕПРАВИЛЬНО: написал код, потом слойную попытку добавить тесты
// Результат: поверхностное покрытие, много false positives

// ПРАВИЛЬНО: тест -> код -> refactor

Ошибка 2: 100% покрытие ради чисел

// НЕПРАВИЛЬНО: тестируем всё подряд, включая getters
@Test
public void testGetters() {
    User u = new User();
    u.setName("John");
    assertEquals("John", u.getName()); // бесполезный тест
}

// ПРАВИЛЬНО: тестируем бизнес-логику
@Test
public void userCanSetEmailAndReceiveNotifications() {
    user.setEmail("john@example.com");
    assertTrue(user.isNotificationEnabled());
}

Ошибка 3: Не пересматривать threshold

// Если project мал — 70% OK
// Если большой и critical — 85-90% нужно
// Пересматривай каждый квартал

Правильный ответ на собеседовании

"Контроль покрытия — это совместная ответственность:

  • Разработчик — пишет тесты вместе с кодом (TDD), проверяет локально
  • Code Review — партнер проверяет completeness тестов
  • CI Pipeline — автоматический gate: если coverage < threshold, PR не merge-ится
  • Лид — устанавливает threshold (обычно 80%), выбирает инструмент (JaCoCo)
  • QA — пишут e2e и интеграционные тесты

Порядок: unit → integration → e2e Инструмент: JaCoCo (Maven) или Cobertura (Gradle) Метрика: Ищем качество, не числа. 80% качественного покрытия > 100% тесты-заглушки."