Unit test code with Jasmine and code coverage with Karma coverage using Istanbul

Karma is an awesome testing environment, it is open source, it supports a plethora of testing frameworks and it is easy to use.

In this post I am going to create some simple tests, run them on Karma using Jasmine and finally, show some code coverage reports, through Karma coverage.

TLDR: Code can be found here.

In this sample, I created a new project, running npm init -y, installing the following dependencies:

  "devDependencies": {
    "istanbul": "^0.4.5",
    "jasmine-core": "^2.5.2",
    "karma": "^1.3.0",
    "karma-coverage": "^1.1.1",
    "karma-jasmine": "^1.0.2",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-chrome-launcher": "^2.0.0"
  }

Next, I setup the test script in package.json.


  "scripts": {
    "test": "karma start karma.conf.js"
  },

Awesome, I am ready to setup the karma.conf.js file to configure Karma. This is added on the root directory of the project and it looks like the following:


module.exports = function (config) {
    config.set({
        basePath: '',
        frameworks: ['jasmine'],
        files: [
            'src/app/**/*.js',
            'src/spec/**/*.specs.js'
        ],
        preprocessors: {
            '**/src/app/*.js': ['coverage']
        },
        plugins: [
            'karma-jasmine',
            'karma-phantomjs-launcher',
            'karma-coverage'
        ],
        reporters: ['progress', 'coverage'],
        port: 9878,
        colors: true,
        logLevel: config.LOG_DEBUG,
        autowatch: true,
        browsers: ['PhantomJS'],
        singleRun: false,
        concurrency: Infinity,
        coverageReporter: {
            includeAllSources: true,
            dir: 'coverage/',
            reporters: [
                { type: "html", subdir: "html" },
                { type: 'text-summary' }
            ]
        }
    });
};

I left the basePath empty, indicating it is the root current directory.

On frameworks I use the Jasmine testing framework for my tests. Because it is an array, I can pass more than one framework for Karma to load. All available frameworks can be found here.

The files property gets all the files that are going to be loaded into the browser. In this case the browser is PhantomJS, as you can see from the browsers configuration property.
All of my code resides into the src directory, which has the app and spec subdirectories. In first there is a calculator.js file, whereas in the latter is a calculator.specs.js file.

On preprocessors, I include only the files that I want a report to be generated, not third party libraries, not specs, just the files that I care to see code coverage reports, in this case the calculator.js. The preprocessors will preprocess the matching files before serving them to the browser.

On plugins property, I register all the required plugins Karma wants to run the configuration. For example, I am using Jasmine as the testing framework, I need to have karma-jasmine plugin loaded into Karma. Same goes for karma-phantomjs-launcher, which loads PhantomJS browser into Karma, in order to be used in browsers configuration, or karma-coverage, which provides code coverage reports using Istanbul.

The reporters configuration takes ‘progress’ and ‘coverage’. The progress reporter will show the number of tests executed, skipped and total in console.
The coverage reporter will create a coverage report for every browser that the tests are run in.

Lastly, skipping rest of configuration, there are the coverage reporter options (last configuration property). By this one can configure the output directory to dump the reports, different type of reporters, like html, text, etc.
In the example above, I output the coverage results in a coverage directory, relative to the root directory of the project. Also, I have configured two different type of reporters to deploy, one html, which will create the reports in an HTML format, under the html subdirectory and one text-summary, which will output a summary of the code coverage on console.

This is the calculator.js, the source to be tested.


function Calculator() {
    function add(x, y) {
        return x + y;
    }

    function subtract(x, y) {
        return x - y;
    }

    return {
        add: add,
        subtract: subtract
    }
}

And this is the corresponding spec:


describe("Calculator Spec", function() {
    it("should add two and two and get four as a result", function() {
        // Arrange
        var calculator = new Calculator();

        // Act
        var result = calculator.add(2, 2);

        // Assert
        expect(result).toBe(4);
    });
});

Let’s run this, by opening a terminal and typing npm test

This is the feedback I get from each reporter:

coverage_summary_notcomplete

And from the HTML…

coverage_html_notcomplete

Seems that I have forgotten to test the subtract method. Istanbul code coverage lets me know about this, by highlighting the not tested code in red.

Let’s fix this by adding a test for this method.


    it("should subtract two and two and get zero as a result", function (){
        // Arrange
        var calculator = new Calculator();

        // Act
        var result = calculator.subtract(2, 2);

        // Assert
        expect(result).toBe(0);
    });

And run the tests again and see the results from the reports…

coverage_summary_complete

And the HTML one..

coverage_html_complete2

coverage_html_complete

Seems like the reports working just fine.

Summary

Karma is awesome and easy, as it was demonstrated in this post and setting up code coverage for your project is equally easy.
We saw how to setup Karma to run tests using Jasmine framework and how to setup code coverage with Istanbul to get reports on coverage. All you need to do is to download the karma-coverage package set the preprocessors, reporters and reporter options and run Karma, simple as that.

Advertisements

One thought on “Unit test code with Jasmine and code coverage with Karma coverage using Istanbul

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s