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.
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.
Now, Karma will continuously run tests in the background while I work.
Easy!