Статьи

Покрытие кода для тестов Жасмин с использованием Стамбула и Кармы

Для разработки современных веб-приложений уже недостаточно иметь десятки модульных тестов. Фактическое покрытие кода этими тестами показало бы, полностью ли приложение нагружено или нет. Для тестов, написанных с использованием знаменитой библиотеки тестов Жасмин , проще всего получить отчет о покрытии через Стамбул и Карму .

Для этого примера давайте предположим, что у нас есть простая библиотека, sqrt.jsкоторая содержит альтернативную реализацию Math.sqrt. Обратите также внимание на то, как он выдаст исключение вместо возврата NaNдля неверного ввода.

var My = {
  sqrt: function(x) {
    if (x < 0) throw new Error("sqrt can't work on negative number");
      return Math.exp(Math.log(x)/2);
  }
};

Использование жасмин , помещенном под test/lib/jasmine-1.3.1, мы можем изготовить тестовый бегун , который включает следующие спецификации:

describe("sqrt", function() {
  it("should compute the square root of 4 as 2", function() {
    expect(My.sqrt(4)).toEqual(2);
  });
});

Открытие специалиста в веб-браузере даст ожидаемый результат:

jasmine_runner

Все идет нормально. Теперь давайте посмотрим, как можно измерить покрытие кода нашей тестовой установки.

Первым делом стоит установить карму . Если вы не знакомы с Karma, это в основном тестовый прогон, который может запускать и подключаться к определенному набору веб-браузеров, запускать ваши тесты, а затем собирать отчет. Используя Node.js, нам нужно сделать следующее:

npm install karma karma-coverage

Перед запуском Karma нам нужно указать его конфигурацию . Это может быть так просто, как показано ниже my.conf.js(большинство записей самоочевидны). Обратите внимание, что тесты выполняются с использованием PhantomJS для простоты, однако довольно просто добавить другие веб-браузеры, такие как Chrome и Firefox.

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      '*.js',
      'test/spec/*.js'
    ],
    browsers: ['PhantomJS'],
    singleRun: true,
    reporters: ['progress', 'coverage'],
    preprocessors: { '*.js': ['coverage'] }
  });
};

Запуск тестов, а также одновременное выполнение кода могут быть инициированы с помощью:

node_modules/.bin/karma start my.conf.js

который выведет вывод как:

INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.2 (Linux)]: Connected on socket N9nDnhJ0Np92NTSPGx-X
PhantomJS 1.9.2 (Linux): Executed 1 of 1 SUCCESS (0.029 secs / 0.003 secs)

Как и ожидалось (из предыдущего ручного вызова специалиста), тест прошел просто отлично. Однако наиболее интересным здесь является отчет о покрытии кода, он хранится (в расположении по умолчанию) в подкаталоге coverage. Откройте отчет в своем любимом браузере, и там вы найдете отчет об анализе покрытия.

branch_uncovered

За кулисами Карма использует Istanbul , комплексный инструмент покрытия кода JavaScript (читайте также мой предыдущий пост в блоге о покрытии кода JavaScript в Стамбуле ). В этом примере Istanbul анализирует исходный файл, sqrt.jsиспользуя Esprima, а затем добавляет некоторые дополнительные инструменты, которые будут использоваться для сбора статистики выполнения. Приведенный выше отчет является одним из возможных выходных данных. Стамбул также может генерировать отчет LCOV, который подходит для многих систем непрерывной интеграции (Jenkins, TeamCity и т. Д.). Обширный анализ данных покрытия должен также предотвратить любую регрессию покрытия в будущем, см. Мою другую публикацию « Жесткие пороги по охвату кода JavaScript» .

Одной из важных особенностей покрытия кода является покрытие филиала . Если вы внимательно обратите внимание, наш тест, описанный выше, все еще не показывает ситуацию, когда входные данные My.sqrtотрицательны. В третьей строке кода есть большой знак «I», это Стамбул, который говорит нам, что ветвь if вообще не берется (для ветви else это будет маркер «E»). Как только эта недостающая ветвь замечена, улучшить ситуацию так же просто, как добавить еще один тест в спецификацию:

it("should throw an exception if given a negative number", function() {
  expect(function(){ My.sqrt(-1); }).
    toThrow(new Error("sqrt can't work on negative number"));
});

После повторного выполнения теста отчет о покрытии кода выглядит лучше, и все довольны.

полный охват

Если у вас возникли трудности с выполнением вышеприведенных пошаговых инструкций, взгляните на подготовленный мной репозиторий Git: github.com/ariya/coverage-jasmine-istanbul-karma . Не стесняйтесь играть с ним и настроить его в соответствии с вашим рабочим процессом!