Покрытие кода

Урок объясняет, что такое покрытие кода, как его измерять в Jest и как не обмануться цифрой.

Покрытие (coverage) — доля кода, которая выполнилась во время тестов; помогает найти непротестированные участки.

Как измерить

Jest умеет считать покрытие встроенно:

npx jest --coverage

В консоли появится таблица, а в папке coverage/ — подробный HTML-отчёт, где видно прямо в коде, какие строки не выполнялись.

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
math.js   |   85.71 |    66.66 |     100 |   85.71 | 14,15
----------|---------|----------|---------|---------|-------------------

Четыре метрики

МетрикаЧто измеряет
Statements (% Stmts)сколько инструкций выполнилось
Branches (% Branch)сколько веток условий пройдено (и if, и else)
Functions (% Funcs)сколько функций вызвано
Lines (% Lines)сколько строк исполнилось

Самая показательная — Branches: легко вызвать функцию, но не проверить её else-ветку.

Почему важны ветки — на чистом JS

Покажем, что вызвать функцию ещё не значит покрыть всё поведение:

function classify(n) {
  if (n > 0) return 'положительное';
  return 'неположительное';
}

// "тест" проверяет только одну ветку
console.log(classify(5));   // зашли в if
// ветка для n <= 0 НЕ выполнилась ни разу
console.log('Покрыта ветка n > 0:', true);
console.log('Покрыта ветка n <= 0:', false);

Вывод:

положительное
Покрыта ветка n > 0: true
Покрыта ветка n <= 0: false

Statements/Lines тут могут показать высокий процент, но баг в ветке n <= 0 остался бы незамеченным. Поэтому смотрят именно на Branches.

100% — не самоцель

Покрытие говорит, какой код выполнился, но не гарантирует, что проверки осмысленны. Можно «прогнать» строку без единого expect — покрытие вырастет, ценности ноль. Гонка за 100% часто рождает бессмысленные тесты. Разумная цель — высокое покрытие ключевой логики, а не магическое число.

Порог покрытия в CI

В конфиге можно задать минимальный порог, ниже которого сборка падает:

{
  "jest": {
    "coverageThreshold": {
      "global": { "branches": 80, "functions": 80, "lines": 80 }
    }
  }
}

Итог

  • jest --coverage показывает, какая доля кода выполнилась.
  • Четыре метрики; ветки (Branches) — самые показательные.
  • Высокое покрытие не равно хорошим тестам: важны осмысленные проверки.
  • Порог в coverageThreshold страхует от падения покрытия в CI.
Проверьте себя
1. Что измеряет покрытие кода?
AСкорость тестов
BДолю кода, которая выполнилась во время тестов
CЧисло строк в проекте
DКоличество багов
2. Почему метрика Branches особенно показательна?
AОна считает строки комментариев
BОна проверяет, что пройдены обе ветки условий, а не только одна
CОна измеряет время выполнения
DОна всегда равна 100%
3. Почему 100% покрытия — не самоцель?
A100% невозможно достичь технически
BПокрытие говорит, что код выполнился, но не что проверки осмысленны; можно поднять процент без единого expect
CВысокое покрытие замедляет CI
DJest не поддерживает 100%
Поддержать проект