Concurrently Testing JavaScript

You’ve heard of nCrunch, right?  It’s a continuous integration plugin for Visual Studio that tracks changes to your code and then automatically builds and runs your unit tests in the background whilst you type.  Once the results are back it decorates every line of code with a red or green light to indicate whether the tests are passing or failing.

image

I have been using nCrunch for a while now and cannot recommend it enough.  It has it’s faults – what doesn’t? – but all things considered it is probably the one add-on that I couldn’t live without.  It speeds up the red/green/refactor cycle to such an extent that working without it feels like you’ve lost a limb.

Where are you going with this?

Good question.  nCrunch is fantastic…for .NET development.  I do a fair bit of work in .NET but more and more I find myself working in JavaScript and desperately missing the constant feedback.

So how can we get something similar for our JavaScript tests?  By using grunt of course!

Testing with Grunt

GruntJS (which I’ve been playing around with recently) can be setup to run QUnit tests using the headless PhantomJS browser and to feedback the results.  In fact, this is all nicely packaged up in the grunt-contrib-qunit package for you, so it’s pretty simple to set up.

To get the tests set up I’m going to assume you have a project structure similar to this one…

image

Installing dependencies with npm

Life is much easier when you don’t have to set stuff up yourself, so let’s use npm to get everything installed.  Drop the following package.json file into the tests folder then open up a node command prompt in the same location.

{
  "name": "myapp-tests",
  "version": "0.0.1",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-cli": "~0.1.9",
    "grunt-contrib-qunit": "~0.2.2",
    "grunt-contrib-watch": "~0.5.3"
  }
}

Run npm install and wait patiently until all the packages are installed.

All done?  Great.

The Gruntfile

Now that we have grunt installed we need to tell it what to do.  Create a new gruntfile.js in the tests folder of the project and drop in the following:

module.exports = function(grunt) {
  grunt.initConfig({
    //configure the qunit task to load test-runner.html
    qunit: {
      files: ['test-runner.html']
    },
    //configure the watch task to react to any changes to *.js
    //in either the src or the current (test) folder
    watch: {
      files: ['../src/**/*.js', '*.js'],
      tasks: ['qunit']
    }
  });

  //load the qunit and watch tasks from npm
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-watch');

  //configure the default task to invoke watch
  grunt.registerTask('default', ['watch']);
};

This file configures the tasks we want to be run by grunt:

  • The qunit task is configured to invoke test-runner.html
  • The watch task is configured to monitor the current and the ../src folders for any changes to a JavaScript file, and to invoke the qunit task whenever a change is made.

We also set up the default task to invoke watch so that it will be run automatically

Fire up a console window and run grunt; you should see something like this:

image

Now go and make a change to target.js

image

As soon as we save any change to a .js file our tests will automatically be run in the background.

True, it isn’t nicely integrated into the IDE, and the level of feedback is very basic compared to nCrunch…but it’s a start!