Journal Contact

Testing jQuery Code with Jasmine, and Gulp


Update: See this post for an updated, better method.

When writing jQuery code or plugins, creating tests for your code should be simple, and out of the way. However, this is not always the case, and can be frustrating for developers who are new to writing tests, and want to get into the habit.

When I write JavaScript, my goto stack is CoffeeScript, using Gulp to compile, and minify it. It would make sense then, that during the build process, I'd want to run tests against my code as well. If your JavaScript code requires jQuery, it suddenly can become tricky for tests to run on the CLI, without using a headless browser like PhantomJS. Fortunately, there's a relatively simple, but not obvious solution for testing this type of code, using jsdom, a javascript implementation of the DOM, for node.js environments.

This tutorial assumes a basic familiarity with how to build and run tasks using Gulp.

If you haven't already, you'll need to install the following gulp plugins, like so:

npm install gulp-jasmine gulp-notify --save-dev

and you'll also need to require them at the top of your gulpfile.js file.

var jasmine = require('gulp-jasmine');
var notify = require('gulp-notify');

Now we just need to make a simple task to run our tests.

gulp.task('test', function () {
  gulp.src('./tests/*.js')
    .pipe(jasmine())
    .on('error', notify.onError({
      title: 'Jasmine Test Failed',
      message: 'One or more tests failed, see the cli for details.'
    }));
});

You'll notice I simply store my tests in a folder called tests. Feel free to structure your tests however you like. We're also firing off a notification whenever a test fails, so that we can correct it as soon as possible.

Ok, let's create our first test! Add a new file in your tests folder, and name it whatever you like.

var jsdom = require('jsdom');
describe('My Plugin', function(){
  var $;
  beforeEach(function(done){
    jsdom.env({
      html: '<html><body></body></html>',
      scripts: ['../vendor/jquery.min.js', '../testplugin.js'],
      done: function(err, window) {
        if (err) console.log(err);
        $ = window.jQuery;
        done();
      }
    });

    it('Should add the class "classy" to the element', function(){
      var el = $('<div></div>').suitUp();
      expect( el.hasClass('classy') ).toBe(true);
    });
  });

Ok, let's break this down a bit. What we're doing is using jsdom to construct a virtual DOM, that can pull in external javascript files, before each test runs. We created a simple $ variable, that's all too familiar to jQuery users, and are simply binding it to window.jQuery, so we can call jQuery functions as we normally would.

If you created a "static" plugin – that doesn't bind to jQuery DOM nodes, but is rather a single object that calls functions, simply created another variable, like you did with $, and bind it to the window object, like this: myPlugin = window.myPlugin;

As you can see, we wrote a simple test that utilizes jQuery, and when we run gulp test, the test will pass.

I hope this will help anyone, looking to get up and writing tests for their jQuery code, quickly and relatively hassle-free. If you have any questions or comments, feel free to reply below, or ping me on Twitter, @syropian.

comments powered by Disqus