Test driving JavaScript with Jasmine, Grunt, Karma, PhantomJS and Node js...nice

Hackered
Saturday, September 6, 2014
by Sean McAlinden

As I've been playing around with Grunt recently, I thought I should write a little intro to using it in a TDD setting. In this intro to JS test driving using Grunt, we will be using the following stack:

  • JavaScript (for writing our code)
  • Grunt (for running the tasks)
  • Jasmine (for writing the tests BDD style)
  • Karma (for running the tests)
  • Node for installing all of the above

Install Node and Grunt

Make sure you have installed node.js and grunt onto your machine.

Create a project directory

Create a directory somewhere on your system. Create a directory called "js" inside your project directory, this is where we will write the javascript code and tests.

Initialise node

Open a command prompt, navigate to the root of your project directory and type the following: npm initThis will run a little command line wizard for creating the packages.json file. You will be asked a number of questions such as the name of the app, the version etc. You can edit any of these directly within the file so don't worry if you make mistakes or want to change your mind.

Add require node modules

At the command prompt run the following:

Install Grunt for the app
npm install grunt --save-dev

Install Karma
npm install karma --save-dev

Install Jasmine for Karma
npm install karma-jasmine --save-dev

Install Grunt for Karma
npm install grunt-karma --save-dev

Install PhantomJS
npm install karma-phantomjs-launcher
--save-dev

Your packages.js should now look something like the following:

{
  "name": "JasmineIntroduction",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-karma": "^0.9.0",
    "karma": "^0.12.23",
    "karma-jasmine": "^0.1.5",
    "karma-phantomjs-launcher": "^0.1.4"
  }
}

We're now ready to go, just need to add a little config.

gruntfile.js

Create gruntfile.js at the root of your project folder and add the following code: (doesn't need to be the root btw, just for this tutorial)

module.exports = function (grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        karma: {
            unit: {
                configFile: 'karma.conf.js'
            }
        }
    });

    grunt.loadNpmTasks('grunt-karma');
    grunt.registerTask('default', ['karma']);
};

As you can see, there is a file called karma.conf.js, we need to create this next.

karma.conf.js

Create a file at the root of your project called karma.conf.jsand just copy the following for now, look up Karma configuration for more details:

module.exports = function (config) {
    config.set({

        // base path, that will be used to resolve files and exclude
        basePath: 'js/',

        // frameworks to use
        frameworks: ['jasmine'],

        // list of files / patterns to load in the browser
        files: [
            '**/*.js'
        ],

        // list of files to exclude
        exclude: [
        ],

        // test results reporter to use
        reporters: ['progress'],

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        logLevel: config.LOG_INFO,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // Start these browsers
        browsers: ['PhantomJS'],

        // If browser does not capture in given timeout [ms], kill it
        captureTimeout: 60000,

        // Continuous Integration mode
        // if true, it capture browsers, run tests and exit
        singleRun: false
    });
};

Run Grunt

In your command line, type grunt and hit enter. All being well you should get an error similar to the following: PhantomJS 1.9.7 (Windows 8): Executed 0 of 0 ERROR (0.001 secs / 0 secs)This is because you have no code or tests at the moment.

Create the test

In the "js" directory create a file called: registration.tests.js and copy in the following code and save the file.

"use strict";

describe("My registration tests", function () {

    it("should return concatenated name", function() {
        var firstName = 'Sean';
        var lastName = 'McAlinden';
        var expected = 'Sean McAlinden';

        var result = registrationUtility.concatName(firstName, lastName);
        expect(result).toBe(expected);
    });

});

Check your command line

If you take a look at the command line, you will now see an error similar to: ReferenceError: Can't find variable: registrationUtilityThis is because Karma is watching the files in the JS directory for any changes and the new test code is looking for a variable called registrationUtility.

Add the code

In the "js" directory create a file called registration.jsand add the following code and save the file:

var registrationUtility = {
    concatName: function(firstName, lastName) {
        return firstName + ' ' + lastName;
    }
};

Check your command line

You will now see the test has passed, you'll have a message similar to: PhantomJS 1.9.7 (Windows 8): Executed 1 of 1 SUCCESS

That's it

There you have have, a relatively small amount of setup and you have Karma continuously running your jasmine unit tests. Nice.