In the first part of this series, I discussed when and how Apigee custom code can be unit tested.
In this article I want to talk about how to measure test coverage to ensure our tests are covering a high percentage of our code.
We can start with a slightly refactored folder structure of the code we wrote in the first part:
- src/ | - LogToLoggly.js - test/ | - LogToLogglyTest.js
Refer to the first part for the source codes for those files.
In order to implement code coverage, we can use a tool called Istanbul. It computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests.
We will hook Istanbul into our workflow using gulp which is my favourite build system.
We start by installing all the dependencies:
npm install gulp -g npm install gulp --save-dev npm install gulp-istanbul --save-dev npm install gulp-mocha --save-dev npm install sinon --save-dev npm install expect.js --save-dev
Create a new file on the root folder called "gulpfile.js":
var gulp = require('gulp'); var mocha = require('gulp-mocha'); var istanbul = require('gulp-istanbul'); gulp.task('test', function (cb) { gulp.src(['./src/*.js']) .pipe(istanbul()) .pipe(istanbul.hookRequire()) .on('finish', function () { gulp.src(['./test/*.js']) .pipe(mocha()) .pipe(istanbul.writeReports()) .pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } })) .on('end', cb); }); });
You can now run this gulp task by:
$ gulp test [14:28:22] Using gulpfile ~/..../gulpfile.js [14:28:22] Starting 'test'... feature: logging to Loggly ✓ should log success responses correctly ✓ should log failure responses correctly 2 passing (49ms) ---------------------|-----------|-----------|-----------|-----------| File | % Stmts |% Branches | % Funcs | % Lines | ---------------------|-----------|-----------|-----------|-----------| src/ | 100 | 100 | 100 | 100 | LogToLoggly.js | 100 | 100 | 100 | 100 | ---------------------|-----------|-----------|-----------|-----------| All files | 100 | 100 | 100 | 100 | ---------------------|-----------|-----------|-----------|-----------| ============= Coverage summary ============= Statements : 100% ( 7/7 ) Branches : 100% ( 2/2 ) Functions : 100% ( 0/0 ) Lines : 100% ( 7/7 ) ============================================ [14:28:22] Finished 'test' after 264 ms
The following line in gulpfile will fail the tests if coverage is below 90% - which is very handy for CI:
.pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } }))
If you fall below the 90% mark, you will get the following output from gulp test:
$ gulp test [15:52:14] Using gulpfile ~/..../gulpfile.js [15:52:14] Starting 'test'... feature: logging to Loggly ✓ should log failure responses correctly 1 passing (31ms) ---------------------|-----------|-----------|-----------|-----------| File | % Stmts |% Branches | % Funcs | % Lines | ---------------------|-----------|-----------|-----------|-----------| src/ | 100 | 50 | 100 | 100 | LogToLoggly.js | 100 | 50 | 100 | 100 | ---------------------|-----------|-----------|-----------|-----------| All files | 100 | 50 | 100 | 100 | ---------------------|-----------|-----------|-----------|-----------| ============= Coverage summary ============= Statements : 100% ( 7/7 ) Branches : 50% ( 1/2 ) Functions : 100% ( 0/0 ) Lines : 100% ( 7/7 ) ============================================= ^ Error: Coverage failed
Once you execute the gulp task, apart from the command line dump of coverage percentages, you will get a folder created, called coverage, which contains HTML coverage reports. Open index.html with your browser.
And here is an example of an HTML report with missing coverage:
Nice example and great use of Gulp
After installing all the above said npm modules I ran the test script directly
.\node_modules\.bin\nyc --all --report-dir=.\coverage --reporter=text .\node_modules\.bin\mocha "test\**\*.js"
which gave me code coverage after mocha script execution. There seems to be problem with gulp-mocha version