JavaScript Unit Test Code Coverage Using NodeJS

DZone 's Guide to

JavaScript Unit Test Code Coverage Using NodeJS

Allow me to show you how to use Node.js to provide JavaScript unit test code coverage. The main tools we will be using to pull this off are Karma and Istanbul. The test we write will be using Jasmine. Read on for more info.

· Web Dev Zone ·
Free Resource

A couple of weeks ago, I showed how to get Node.JS and Gulp working with Visual Studio 2015.  Last week, I showed you how to bundle, minify, and cache-bust using Gulp.  This week, we are going to use Node.js to provide JavaScript unit test code coverage.

The main tools we will be using to pull this off are Karma and Istanbul.  The test we write will be using Jasmine.

If you don’t use Visual Studio, you should still be able to adapt these instructions to your own environment.  I’ve found getting Istanbul set up kind of tricky at times.  Since everything I’m going to show you here is pure Node.JS, you can ignore the Visual Studio parts.

Let’s get started.


I’m going to assume that you’ve already got a project set up.  For the purposes of this discussion, we are going to assume that the files we want to test are in the /app directory and that our tests are in the /jsTest directory.

If you are using Visual Studio, one of the first questions you might have is, “if I put my tests in the same project as the app I am testing, won’t those tests get deployed with the application?”  And, the answer to that question is, “Yes, if you use the defaults.” But, we aren’t going to use the defaults.  What we are going to do is make sure that any files we create that we don’t want to deploy to the web server have their build action set to “none”.  You can find this in the file’s property window.

The other way you could solve this problem is that you could have a deploy script written in Gulp that specifies exactly what files should be deployed.

A Simple Demo File

Just so we have something to test, I’ve created a really simple demo JavaScript file that looks like this:

(function() {
    function demo() {
        var self = this;
        function add(a, b) {
            return a + b;

        self.add = add;

    window.demo = demo;

Yes, just a simple add function.  But, that is all we need today.

Image title

And a Simple Test

(function(describe,it,expect) {
      function () {
        var demo;
        beforeEach(function() {
            demo = new window.demo();
        it('demo should truthy', 
          function() {
    window.it, window.expect);

Image title

Install Karma and Istanbul

The next thing you’ll want to do is to install Karma and Istanbul.  This is rather trivial because you can install both with one NPM command.

npm install karma karma-cli karma-coverage --save-dev

Install Karma-Jasmine

npm install karma-jasmine --save-dev

If you are using some other test runner, you’ll need to install the appropriate karma package for it.

Install PhantomJS

This is the final install you will need to make.  The truth of the matter is that you can use any browser to run your test.  But, normally, you’ll want to use a headless browser so that you can run the tests in your continuous integration server.

When I am interested in seeing if my tests passed during development, I’ll run the tests in a regular browser using a regular HTML file.  Standard, old, jasmine tests.  When I want to see the code coverage, I’ll use PhantomJS.

To use PhantomJS, go to the site and download the zip file that contains the EXE and place it in your PATH environment variable.  Or, you can place it in a known location relative to your project and you can call it directly.  For this demo, we will place it in /jsTests/phantomjs.

You will also need the phantom launcher.  There are several available, but the one I use just installs the launcher and assumes you already have it installed.

npm install karma-phantomjs-launcher-nonet –save-dev


The last step is to create a karma.conf.js file.  I typically put this in my jsTests directory because it is part of the test files.

Your Karma.conf.js file should contain content that looks something like this:

module.exports = function (config) {
    var path = require('path');
        browsers: ['PhantomJS'],
        phantomjsLauncher: {
            cmd: {
                win32: path.join(__dirname,
        // this tells Karma to start Jasmine
        frameworks: ['jasmine'],
        files: [

        // coverage reporter generates the coverage 
        reporters: ['progress', 'coverage'],

        preprocessors: {
            '../app/**/*.js': ['coverage']

        // optionally, configure the reporter 
        coverageReporter: {
            type: 'html',
            dir: 'coverage/'

Run Your Tests

Unlike many of the demos for running Karma that are available.  We are going to run our tests in a slightly different way.  Using Gulp.

Most people know of Gulp as a file processing tool.  But, here we are going to just use its task running capability.

var gulp = require('gulp');
var Server = require('karma').Server;

gulp.task('test', function (done) {
    new Server({
        configFile: __dirname + '\\jsTests\\karma.conf.js',
        singleRun: true,
        browserNoActivityTimeout: 60000
    }, function () { done(); }).start();

This simple task will run Karma for you using the karma.conf.js file we just created in jsTests.

If you want to have this run every time a file changes once you’ve kicked off this task, change singleRun to false.  As it is written, it only runs the tests on demand.

JavaScript Unit Test Code Coverage

So, hopefully, you’ve got everything running correctly.  Let’s look at the results.

The output for the code coverage should now be in /jsTests/coverage/PhantomJS* directory.  Load the index.html file in your browser.

You should see a screen that looks something like this:


Click on ‘app/’ to see this:


And finally, click on ‘Demo.js’ to see


The Shortcut

Fortunately for you, I’ve created a project on GitHub with all of this already done.

jasmine, javascript, unit test, web design and web development

Published at DZone with permission of Dave Bush , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}