Karma Is Not Just For AngularJS

Tuesday, August 19, 2014

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.

Karma in action!

Now, Karma will continuously run tests in the background while I work.

Easy!


Comments
gravatar Ken Wednesday, August 20, 2014
Hi Scott, Thanks for this article, I saw you demoed Karma in your Getting Started with JavaScript course on Pluralsight but didn't have a clue what kind of tool it was. I've been getting into the Node front-end development after your NDC 2014 video (very insightful video by the way) and using the tools you've mentioned in that video for my personal learning. Now I run my test with gulp task + gulp-jasmine to keep watching of any changes in my tests folder and re-execute the tests everything my test file changes. These tools are so flexible, one could only wish it came out 10 years earlier. I really enjoy the productivity boost these tools have given me. I have a few questions though: 1. Just out of curiosity, what testing framework/tools do you use for your day-to-day job with JavaScript/Node? 2. Is that Jasmine, that you are using in this article withe the pointSpec? Many thanks, Kind Regards, Ken
gravatar Scott Thursday, August 21, 2014
@Ken: 1. Grunt, sometimes gulp, but also bower and a live reload are the first things that come to mind. 2. I am a fan of Jasmine, and that's what the pointSpec is written in.
gravatar Mark Friday, August 22, 2014
Hey Scott, I was intrigued by your PhantomJS (headless) test and downloaded the PhantomJs.exe and put it in my Windows 7 path, but Karma seems to try and load "PhantomJS" and errors due to PhantomJs not being registered. Do I need to install a PhantomJs Karma plugin or something?
gravatar Scott Sunday, August 24, 2014
@Mark: If you do through karma init, it should download everything you need. If not, you'll have to npm install tools: pantomjs and karma-phantomjs-launcher. Hope that helps.
Your Comment
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!