How to setup Karma JavaScript test runner

Karma is a test runner developed by the Angular team trying to bring a productive test environment to developers. As a test runner it allows us to run our client side JavaScript tests in real browsers from the command line.

Though we find plenty of information about Karma on their website, I found it not all obvious what the different configuration settings in its config file do. We try to explain this using an example project.

JavaScript project with Karma, mocha and chai

The project has the following directory structure (get if from github):

// Contains all source files
src/js/
src/vendor/

// Contains the tests
tests/unit/

// Contains nodejs modules
node_modules/

Install testing libs

First, install Karma and some plugins:

// Install karma, mocha adapter and chai
npm install karma karma-mocha chai --save-dev

Everything is installed in the node_modules directory. Karma is the test runner. As a test runner it:

  • Starts a webserver to serve our JavaScript source and test files
  • Loads all files in the correct order
  • Spins up browsers to run our tests in

Mocha is a test framework. It is responsible to run our tests and report back which failed.

Chai is an assertion library. It provides a nice api to check whether our code does the things we expect it to do.

Create Karma config file

Next we create the Karma config file in our directory root:

// Create Karma config file
./node_modules/karma/bin/karma init

This will prompt us for some questions and generates a config file. Items of interests to us are:

basePath: '',

The base path tells Karma where to load our files from. Setting it to '' means all files will be looked up from the root of our project.

files: [
    "node_modules/chai/chai.js",
    "src/**/*.js",
    "tests/**/*.js"
],

Files tells Karma which files it should load relative to the base path. These are:

  • All test related libraries
  • Our source code to test
  • The tests themselves

Note we instruct Karma to load chai.js. Forgetting this means chai will not be loaded.

What about Mocha? Doesn't it need to be loaded too?

Yes it should. However, Karma will autoload all sibling node modules starting with karma-. This means if Karma is installed in the node_modules directory, all other modules starting with karma- will be autoloaded for us. And mocha is fetched as the karma-mocha node module. No need to manually load it ourselves.

frameworks: ['mocha'],

Frameworks instructs Karma to use the mocha testing framework.

browsers: ['Chrome'],

Browsers tells Karma to run the tests in Chrome. Note, Chrome needs to be installed on our computer. Running the tests from the command line will spin up a new Chrome window.

The karma-chrome-launcher node module needs to be installed too. karma init command will auto install it for us. If you add a browser later on, don't forget to install its runner too.

port: 9876,

Karma will start its own server on this port to serve our JavaScript files and tests. The default is ok, only change it when we're already using that port.

autoWatch: true,

Auto watch instructs Karma to rerun the tests whenever a file changes.

singleRun: false

Single run tells Karma to shut down the browser when all tests have ran. This is useful for Continuous Integration systems where only one run is needed. For development, set it to false as this will keep the browser window opened. This means no time is wasted spinning up a new browser every time tests need to be executed.

Run the tests

Now we can run the tests like:

./node_modules/karma/bin/karma start

Notice we can also run the tests with ./node_modules/karma/bin/karma run. This will not spin up the server to load our test files. Use it in combination with karma start. Start will spin up the browser and load the files, run will instruct karma to rerun the tests.

Use karma-cli

It's tiresome to always do ./node_modules/karma/bin/karma start instead of just karma start. Therefore install karma-cli globally.

npm install -g karma-cli

This tool executes the Karma commands for the project in the current directory. By exposing the commands in a separate module then the Karma implementation, we can use different versions of Karma for different projects on our computer.

Note: we might have installed Karma globally before. If so, we need to delete it first as it will mess up which plugins it will autoload. For example: we might have installed karma-mocha in our project dir but not globally. Executing Karma (as global installed module) will fail to load karma-mocha (since "global" Karma will only look into the globally installed modules). Just uninstall karma as a global module and install karma-cli globally instead.