The AngularJS team created Karma, but Karma isn’t tied to AngularJS. As a test runner, I can use Karma to run tests against any JavaScript code using a variety of testing frameworks in a variety of browsers. All I need is Node.js.
Pretend I am writing code to represent a point in two dimensional space. I might create a file point.js.
var Point = function(x,y) {
this.x = x;
this.y = y;
}
I’ll test the code using specifications in a file named pointSpecs.js.
describe("a point", function() {
it("initializes with x and y", function() {
var p1 = new Point(3,5);
expect(p1.x).toBe(3);
expect(p1.y).toBe(5);
});
});
What Karma can do is:
- Provide web browsers with all of the HTML and JavaScript required to run the tests I’ve written.
- Automate web browsers to execute all the tests
- Tell me if the tests are passing or failing
- Monitor the file system to re-execute tests whenever a file changes.
Setup
The first step is using npm to install the Karma command line interface globally, so I can run Karma from anywhere.
npm install karma-cli –g
Then I can install Karma locally in the root of my project where the Point code resides.
npm install karma --save-dev
Karma requires a configuration file so it knows what browsers to automate, and which files I’ve authored that I need Karma to load into the browser. The easiest way to create a basic configuration file is to run karma init from the command line. The init command will walk you through a series of questions to create the karma.conf.js file. Here is a sample session.
>karma init
Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine
Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no
Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> PhantomJS
> Chrome
>
What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> js/**/*.js
> specs/**/*.js
>
Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>
Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes
Config file generated at "C:\temp\testjs\karma.conf.js".
I can open the config file to tweak settings and maintain the configuration in the future. The code is simple.
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'js/**/*.js',
'specs/**/*.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS', 'Chrome'],
singleRun: false
});
};
Note that when I enter the location of the source and test files, I want to enter the location of the source files first. It’s helpful if you can organize source and test files into a directory structure so you can use globbing (**) patterns, but sometimes you need to explicitly name individual files to control the order of loading.
At this point I can start Karma, and the tests will execute in two browsers (Chrome, which I can see, and PhantomJS, which is headless). I’d probably tweak the config file to only use Phantom in the future.