Journal Contact

Javascript Testing With Jasmine and Gulp: Redux


Last year I wrote a post on testing JS code using Gulp and Jasmine. It used a combination of gulp-jasmine to run the tests and jsdom to inject dependencies. It was an ok solution, but I've since revisited the idea, and have determined a much better way of doing it. This method is actually not entirely specific to Jasmine either, if you prefer to swap it for something else, like Chai.

The main idea here is to use Karma and PhantomJS to power your testing framework.

Once again, this tutorial assumes a basic familiarity with Gulp and task runners in general.

First of all we need to install some dependencies:

npm install karma karma-jasmine karma-phantomjs-launcher karma-spec-reporter --save-dev

Now that we have our dependencies installed, let's open up our gulpfile and add a task. First we need to require in our Karma server:

// gulpfile.js
var Server = require('karma').Server;

Now we'll create a task called test that will fire up our Karma server:

// gulpfile.js
gulp.task('test', function (done) {
  return new Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true
  }, done).start();
});

Good stuff. However, you'll notice we're specifying a config file that we probably haven't made yet. Let's do that now. Create a karma.conf.js file in your root and open it up. Here we'll add the basic configuration, as well as our list of files it needs to run your tests. Here's mine:

// karma.conf.js
module.exports = function(config) {
  config.set({
    frameworks: ['jasmine'],
    reporters: ['spec'],
    browsers: ['PhantomJS'],
    files: [
      'libs/jquery-1.11.3.min.js',
      'myscript.js',
      'tests/**/*.js'
    ]
  });
};

You'll notice I included jQuery, simply to show how to add a dependency of myscript.js. You should always include the dependencies of your own code first, then your own code, and your tests at the end.

All that's left now is to write your tests, fire up your CLI, and run gulp test. Here's my sample output:

[gulp] Running 'test'...
02 08 2015 18:21:17.343:INFO [karma]: Karma v0.13.3 server started at http://localhost:9876/
02 08 2015 18:21:17.364:INFO [launcher]: Starting browser PhantomJS
02 08 2015 18:21:19.432:INFO [PhantomJS 1.9.8 (Mac OS X 0.0.0)]: Connected on socket pPqnnG8OjuOWVUaIAAAA with id 65955841

  Testing the plugin
    ✓ should init
    ✓ should do something
    ✓ should work with jQuery

PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 3 of 3 SUCCESS (0.002 secs / 0.002 secs)
TOTAL: 3 SUCCESS

[gulp] Finished 'test' in 2.23 s

So what if we want to continually test while we write our code? Regular gulp watchers don't work all that great with Karma, but fortunately it's still extremely simple. Go ahead and create a new gulp task called tdd. This task is going to look very similar to our test task, but we're going to simply omit the singleRun: true line. This causes Karma to use its own watcher, that will work much more reliably. Here's mine:

gulp.task('tdd', function (done) {
  new Server({
    configFile: __dirname + '/karma.conf.js',
  }, done).start();
});

That's all there is to it! A clean, simple way of testing your front-end code with Gulp, Jasmine, Karma, and PhantomJS. If you have any questions or comments, reply below, or boop me on Twitter, @syropian.

comments powered by Disqus