JavaScript testing with Karma and Jasmine

I have been using Jasmine running in the browser to test my JavaScript for a while now. Coming from the background of RSpec the syntax is reassuringly similar. However running tests in the browser has several downsides. First there is a rather annoying html file that is required to hold the code and tests together. Second running the tests like this means opening up a browser and moving away from the terminal. This is an annoyance most of the time and completely unsuitable to work with continuous integration. The solution to both this problems is to work with a command line tool, in this case karma.

image

Karma runs on node.js and is easiest installed using the node package manager (npm). If you have not got either of these installed checkout my post on getting started with node and npm.

Karma is a test runner and requires a test framework to work with. Supported frameworks are jasmine, qunit and mocha. A discussion of the differences between these is beyond this post. In summary I chose Jasmine as it is the most complete without add ons.

Karma also requires a browser to run the tests and a plugin to handle that browser. Supported browsers are Chrome, ChromeCanary, FireFox, Safari, PhantomJS, Opera and InternetExplorer.

Getting started the first step is to initialise a node project then add the test dependencies to package.json.

“devDependencies”: {
    “karma-jasmine”: “~0.1.3”,
    “karma-phantomjs-launcher”: “~0.1.1”,
    “karma”: “~0.10.6”,
    “karma-spec-reporter”: “0.0.12”,
  }

Running ‘npm install’ will install all of the packages locally to node. At this point to run any of the karma commands you will be required to enter the whole path, to run the tests for example is likely to be.

$ ./node_modules/karma/bin/karma start

This is tedious and fortunately karma also has a tool to add these commands to your path. To add the command karma to the terminal the package karma-cli needs to be installed globally. 

$ npm install -g karma-cli

$ karma start  // same as long command above

The configuration settings are kept in karma.conf.js. Here you set how you would like to format the output, whether to run continuously and what files to load. There are a lot of whys to set up karma, this is my preference.

module.exports = function(config) {
  config.set({
    basePath: “,
    frameworks: ['jasmine’],
    files: [
      'bower_components/path/to/dependency.js’,
      'src/*.js’,
      'spec/**_spec.js’,
    ],
    reporters: ['spec’],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['PhantomJS’],
    captureTimeout: 60000,
    singleRun: true
  });
};

An important thing to note is to remember to load up all your dependencies, also when using wildcards the files will be added in alphabetical order. When the order is important then that will need to be declared specifically. It took me a while to spot that one as the first three projects I did the correct order was alphabetical order

I always use the test suite as a single run through. As the test suites I have written so far take less than 1 sec I have always been happy to explicitly run them. This also works well with continuous integration.  

Finally the 'spec’ reporter is not included by default and needs to be added through node

$ npm install karma-spec-reporter –save-dev

That’s getting started with karma, but doesn’t cover writing any of the tests. That is because karma can run many different flavours of tests. A simple test framework to start with is Jasmine, which has an exceptionally clear introduction to the basics and several more powerful techniques. There is also a great supply of plugins for handling fixtures, asynchronous code and more. Because Jasmine offers such a complete solution I have not always found it the easiest to integrate plugins with. For this reason I want to try mocha which is an alternative test framework that can be run on karma, and will hopefully be reported on in the future.