I strongly believe in usefulness of code coverage information. Recently I added code coverage badges to my open source JavaScript projects using coveralls.io. Here is a sample of badges from qunit-promises:
The code coverage badge is just an image href provided by the coveralls website, included into the README.md
[![Coverage Status][qunit-promises-coverage-image]][qunit-promises-coverage-url]
[qunit-promises-coverage-image]: https://coveralls.io/repos/bahmutov/qunit-promises/badge.png
[qunit-promises-coverage-url]: https://coveralls.io/r/bahmutov/qunit-promises
Anyone looking at this project can quickly make initial judgement about its quality: working build, high unit test code coverage, up to date dependencies.
I aggregate these badges into larger Markdown based status board.
Collecting code coverage
I use popular JavaScript code instrumentation tool istanbul to instrument the nodejs code on the fly in my testing framework gt. gt saves both HTML report and line by line coverage file lcov.info after each run. The line coverage file looks something like this:
TN:
SF:/qunit-promises/qunit-promises.js
FN:1,(anonymous_1)
FN:4,verifyPromise
FN:18,alwaysName
FN:30,(anonymous_4)
... continues
Each line starts with a type of covered structure, in this case FN means a function was covered, followed by its source line and additional information (function name). There are records for functions, lines and branches.
I prefer looking at the HTML reports saved by istanbul, here is the same information in the user-friendly format
Notice the covered anonymous function at line 1, verifyPromise at line 4, etc.
Sending line coverage to Coveralls
Coveralls service is free for open source projects hosted on Github. The read access to Github is important: Coveralls needs a copy of the source to show line by line report together with the coverage stats. While Coveralls is compatible with multiple build systems, it integrates right away with Travis-ci.
First, install coveralls
node module as a dev dependency in your project
npm install coveralls --save-dev
. Second, define a command to pipe lcov.info
file to the module's bin file. For example in package.json
"scripts": {
"test": "grunt && npm run gt",
"gt": "node ./node_modules/gt qunit-promises.js test/node-tests.js --output",
"coveralls": "cat cover/lcov.info | ./node_modules/coveralls/bin/coveralls.js"
}
Coveralls.js script literally does nothing, but reads standard input and then sends it to the server
#!/usr/bin/env node
var handleInput = require('../lib/handleInput');
var logger = require('../lib/logger');
process.stdin.resume();
process.stdin.setEncoding('utf8');
var input = '';
process.stdin.on('data', function(chunk) {
input += chunk;
});
process.stdin.on('end', function() {
handleInput(input, function(err) {
if (err) {
throw err;
}
});
});
If you decide to send the data from local machine, instead of Travis-ci, you would need to provide your project's secret token (see Coveralls.io docs). I setup my project's .travis.yml to send coverage info after a successful build.
# .travis.yml
after_success:
- npm run coveralls
That's it. Every time Travis builds my project, code coverage gets sent to coveralls, where it is aggregated (after certain time delay, I noticed). In addition to badges, the service provides historical trend data, as well as line by line source view.