Add code coverage to your Node.js projects

19 June 2013, Amsterdam
Send to Kindle

Note: This blog post is heavily based on Xavier Seignard's blog post. He gives a longer introduction on it, and integrates it together with Sonar. You should check it out.

Code coverage is invaluable to get an overview of how well-tested your app is, and it helps finding new bugs in your code. Unfortunately coverage reports are not ubiquitous in Node.js projects, and because of that it may seem that it is hard to set up, which is not the case at all!

I'm going to show you how to set up code coverage using Mocha, Istanbul and LCOV in two easy steps.

Step 1: Install dependencies

First we'll install LCOV, which is a graphical frontend for the gcov tool and can parse the output of code coverage info files. The gcov format is a universal format for code coverage stats.

In OSX (using homebrew):

brew install lcov

In linux (Ubuntu):

apt-get install lcov

Now we declare the remaining dependencies in the package.json of your project:

{
  "devDependencies": {
    "mocha": "~1.10.0",
    "istanbul": "~0.1.36",
    "mocha-istanbul": "~0.2.0"
  }
}


Step 2: Set up a Makefile

With everything installed, we just need to automate the process of generating the coverage report. I am using a Makefile to do that, but it could be a simple script. After all, it is just executing bash commands.

We first create a file named Makefile in the root of our project folder and declare some variables containing the location of executables and a filter for test files:

#!/bin/bash

MOCHA=node_modules/.bin/mocha
ISTANBUL=node_modules/.bin/istanbul

# test files must end with ".test.js"
TESTS=$(shell find test/ -name "*.test.js")

After that, we make a case for generating a coverage report:

coverage:
    # check if reports folder exists, if not create it
    @test -d reports || mkdir reports
    $(ISTANBUL) instrument --output lib-cov lib
    # move original lib code and replace it by the instrumented one
    mv lib lib-orig && mv lib-cov lib
    # tell istanbul to only generate the lcov file
    ISTANBUL_REPORTERS=lcovonly $(MOCHA) -R mocha-istanbul $(TESTS)
    # place the lcov report in the report folder,
    # remove instrumented code and put back lib at its place
    mv lcov.info reports/
    rm -rf lib
    mv lib-orig lib
    genhtml reports/lcov.info --output-directory reports/

In the preceding code Istanbul instruments our source code in the lib folder, so anything outside of lib won't be taken into account by the code coverage report. The original folder is not modified, just renamed while the coverage report is generated. After that, lib is restored to its original name and I get rid of other folders generated in the process.

You should change lib to the location of your source code.

As a nice final touch, we can add two extra actions to our Makefile, clean and test:

clean:
    rm -rf reports

test:
    $(MOCHA) -R spec $(TESTS)

With this, we now have available a coverage action in the Makefile. So we can execute the following in the root of our project folder:

make coverage

and Istanbul will generate a complete report in the report folder. You can now go there and open index.html to see your coverage by lines, functions and files.

Happy testing!


If you'd like, you could follow me on twitter, Google+ or drop me an Email.

comments powered by Disqus