Анализ покрытия JavaScript-кода тестами
Я попробую совсем коротко рассказать о том, как измерять покрытие NodeJS-проектов на GitHub с бейджами и тревисом. В принципе, это применимо и к модулям для браузера, ведь ничего не мешает тестировать их под NodeJS с JSDom.
И сразу дисклеймер — утилит для инструментирования и тестирования, ровно как и облачных сервисов очень много. Я использую mocha для тестов, jscoverage для инструментирования и Coveralls прикрученный к Travis как CI-сервис для анализа покрытия. Просто потому что я так привык.
Зачем знать процент покрытия тестами?
Нельзя улучшить то, что не нельзя измерить. Это утверждение подходит и для тестов. Хотя, писать тесты уже само по себе хорошо, но это только первый шаг. Следующая ступень — измерять процент покрытия кода.
Как и любая объективная метрика — процент покрития влияет на качество. Просто потому что это наглядно, понятно, ну и из-за классных зёленых бейджей — они-то уж точно всё делают лучше!
Без анализа покрытия, надежность тестов очень размыта. Хотя, не стоит считать это серебрянной пулей — программы для анализа тоже могут ошибаться.
Инструментирование и анализ кода
Если файл один…
Инструментируем модуль:
cd my-project
jscoverage index.js index-cov.js
Затем при тестировании покрытия нужно подключить специально подготовленную cov
-версию эту версию вместо настоящей библиотеки.
Для этого логичнее всего использовать переменную окружения. Советуют называть эту переменную MYPROJECT_COV
.
Некоторые библиотеки используют просто COV
, но у меня возникли конфликты где-то в jscoverage
, так что
лучше добавлять префиксом название проекта.
/* test/index.js */
var myProject = process.env.MYPROJECT_COV
? require('../index-cov')
: require('../index');
Теперь остается запустить тесты и сгенерировать отчет о покрытии. Делается это так:
MYPROJECT_COV=1 ./node_modules/.bin/mocha -R html-cov > coverage.html
Файлы coverage.html
и index-cov.js
стоит добавить в .gitignore
, чтобы не закоммитить случайно.
Если файлов много…
Если в проекте много JS-файлов, которые скрываются за index.js, то обычно все эти штуки убираются в lib/
,
который инструментируется в lib-cov/
:
cd my-project
jscoverage lib lib-cov
В index.js
остается только код, который, в зависимости от переменной окружения подключает lib/
или lib-cov/
:
/* index.js */
module.exports = process.env.MYPROJECT_COV
? require('../lib-cov')
: require('../lib');
Ну и в tests/
проверять переменную окружения уже не нужно — так что там не остается ничего необычного.
Не забудте добавить lib-cov/
в .gitignore
.
Coveralls
Окей, Google. Теперь мы знаем насколько наш модуль покрыт тестами — можно смотреть в coverage.html
, улучшать
покрытие тестами, и всячески делать этот мир лучше.
Но вот беда — coverage.html
есть только локально, да и при каждой генерации
отчета о покрытии он перезаписывается, не оставляя никакой истории, и, соответственно,
возможности наблюдать прогресс. Если вы разрабатываете небольшой модуль — наверное, в этом нет ничего страшного.
Но если вы пишете что-то посложнее, то, скорее всего, вам хотелось бы знать, какое покрытие кода
в разных бранчах, пулл-реквестах, иметь возможность заглянуть в историю. А как насчет
клёвого бейджа —
в
readme.md
?
Насколько я знаю, таких сервисов не мало. К примеру, code climate может следить за покрытием кода. Я же пока остановился
(хотя, конечно, я только начал :D) на Coveralls. Coveralls интегрируется с Travis CI. В .travis
нужно будет добавить несколько
скриптов, которые после завершения обычного тестирования будут запустят тесты на покрытие и отправят результаты на сервер
Coveralls.
after_success:
- ./node_modules/.bin/jscoverage lib lib-cov
- MYPROJECT_COV=1 ./node_modules/.bin/mocha test -R mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
package.json
Для работы Coveralls понадобится парочка модулей:
mocha-lcov-reporter
, который адаптирует данные о покрытии кода вlcov
-формат, с которым работает Coveralls,coveralls
— CLI-реализация API coveralls.
Кстати, ничего не мешает вынести вынести генерацию coverage.html
в package.json
— не писать же руками каждый раз:
// package.json
"scripts": {
"test": "mocha",
"test-cov": "jscoverage lib lib-cov; MS_COV=1 ./node_modules/.bin/mocha -R html-cov > coverage.html",
// ...
}
Теперь можно просто писать npm run test-cov
и не вспоминать нужные команды каждый раз. Осталось
только бейдж из coverals в readme.md
добавить.
Примеры
В примерах можно посмотреть .travis.yml
, package.json
и покликать на бейджи:
- ms-to — небольшая утилита для работы с миллисекундами в JS.
- page.js — роутер в духе ExpressJS только для браузера.
- microlog — небольшой и удобный логгер для NodeJS приложений.
фото: Cyril Bosselut
Подписывайтесь на РСС. Всем добра и штурмовиков.
Похожие статьи:
-
Попробовал в TDD. Люто-бешено доставляет
После того, как я начал писать тесты я серьезно изменил отношение к написанию кода.
-
Музыка для работы #5
Немного мурашек по спине…
-
Белый шум
Баттхёрта нить начинается здесь
-
CommonJS для браузера
Видео моего доклада на MoscowJS
-
Музыка для работы #4
Трогательный chillwave, dream pop & glich
-
Instapaper и Pocket
К чёртовой матери ссылки!
-
Byobu
Текстовый тайловый менеджер для Linux и OS X
-
Чейнинг
или Как сделать код проще, добавив одну строчку