Уровни покрытия: statement, branch, function, line

В тестировании на JavaScript, особенно при использовании Vue и Vue Test Utils, важным аспектом является измерение покрытия кода (code coverage). Покрытие позволяет оценить, насколько тесты охватывают функциональность приложения. Существует несколько уровней покрытия: statement, branch, function, line. Каждый из них имеет своё значение и помогает выявлять пробелы в тестировании.


Statement Coverage

Statement coverage измеряет, какие выражения (операторы) были выполнены во время запуска тестов. Любая инструкция в коде считается “statement”:

function sum(a, b) {
  const result = a + b; // statement
  return result;        // statement
}

Если тест вызывает sum(2, 3), оба оператора будут покрыты. Недостаток statement coverage в том, что оно не учитывает все возможные ветвления внутри выражений, поэтому может создать иллюзию полного тестирования, даже если условные конструкции проверены не полностью.


Branch Coverage

Branch coverage — это измерение выполнения всех возможных веток в логических конструкциях (if, switch, тернарные операторы). Оно показывает, были ли проверены все возможные исходы условий:

function checkNumber(n) {
  if (n > 0) {
    return "positive"; // ветка 1
  } else {
    return "non-positive"; // ветка 2
  }
}

Чтобы достичь полного branch coverage, необходимо протестировать функцию с положительным числом и с нулем или отрицательным числом. Branch coverage позволяет выявлять скрытые ошибки, которые могут не проявляться при покрытии только statement.


Function Coverage

Function coverage фиксирует, были ли вызваны все функции в коде хотя бы один раз. В Vue-компонентах это особенно важно для методов компонентов:

export default {
  methods: {
    greet(name) {
      return `Hello, ${name}`;
    },
    farewell(name) {
      return `Goodbye, ${name}`;
    }
  }
}

Если тест вызывает только greet, функция farewell остаётся непокрытой. Function coverage даёт быстрый обзор того, какие методы или функции не были проверены, что полезно при комплексном тестировании компонентов Vue с множеством методов.


Line Coverage

Line coverage измеряет, какие строки кода были выполнены во время тестов. Это более детализированное покрытие, чем statement, и показывает конкретные строки, которые были или не были использованы:

function checkAge(age) {
  if (age >= 18) {
    return "adult"; // line 2
  } else {
    return "minor"; // line 4
  }
}

Line coverage помогает визуально определить, какие строки остаются неиспользованными, и часто используется вместе с statement и branch coverage для анализа полноты тестов.


Связь уровней покрытия

  • Statement и line покрывают отдельные инструкции; line более наглядно показывает конкретные строки.
  • Branch обеспечивает проверку всех логических исходов.
  • Function фиксирует вызовы функций, независимо от их содержимого.

Полное тестовое покрытие обычно требует комбинирования этих метрик. В Vue Test Utils:

  • mount и shallowMount позволяют вызвать методы и обработчики событий, увеличивая function и statement coverage.
  • Использование trigger событий и проверка различных пропсов помогает покрыть все ветви (branch coverage).
  • Снимки компонентов и проверка DOM-вывода способствуют line coverage.

Практические примеры измерения покрытия

С Vue CLI проектами используется интеграция с Jest:

vue add unit-jest

Запуск тестов с покрытием:

npm run test:unit -- --coverage

Отчёт включает таблицу с метриками:

File % Stmts % Branch % Funcs % Lines
HelloWorld.vue 95 90 100 95
  • % Stmts — statement coverage
  • % Branch — branch coverage
  • % Funcs — function coverage
  • % Lines — line coverage

Разница между statement и line coverage проявляется, когда одна строка содержит несколько выражений: statement может быть покрыт частично, но строка считается выполненной полностью. Branch coverage показывает, какие логические пути ещё не проверены.


Особенности Vue-компонентов

  1. Методы и computed Function coverage фиксирует вызовы всех методов и вычисляемых свойств.

  2. Условный рендеринг v-if, v-else-if, v-else требуют branch coverage для каждой ветки.

  3. События и слоты Для полной statement и line coverage важно тестировать события с wrapper.trigger() и контент слотов.

  4. Watchers Если watcher реагирует на изменения пропсов или данных, покрытие функций зависит от тестов, которые изменяют эти значения.


Выводы по практике

  • Statement и line coverage помогают убедиться, что код вообще выполняется.
  • Branch coverage гарантирует проверку всех логических условий.
  • Function coverage показывает, что все функции действительно были вызваны.
  • В Vue Test Utils комбинированный подход позволяет детально оценить качество тестов и выявить пропущенные сценарии.

Эти уровни покрытия являются фундаментальными инструментами для создания надёжного и масштабируемого тестирования Vue-приложений.