October 11, 2013

Unit Testing with Durandal

Durandal provides the Durandal Test Framework for unit testing. This test framework uses PhantomJS and Jasmine.

As shipped with Durandal, it's focused on testing Durandal's own internal components. But it can easily be adapted for your own unit testing needs.

You can obtain the test framework by downloading the entire Durandal project with

git clone https://github.com/BlueSpire/Durandal.git

(assuming, of course, you have git installed).

Note that if you're not on Windows, you'll also need to install PhantomJS on your system, since the PhantomJS that comes with the Test Framework is a .exe.

In your own work, you're probably not going to want to use the entire Durandal project -- you may start with a starter kit such as the HTML Starter Kit, or even with your own custom setup. The first challenge is that the Starter Kits don't include the Test Framework. Beyond that, since the Test Framework is configured out-of-the-box for Durandal's internal testing needs, its hardcoded paths don't work for the directory hierarchies you'll have as a developer.

But configuring the Test Framework for your own needs is very easy. Edit spec.html in the test directory. In that file, you'll see that require is configured with some paths:

    paths: {
        'specs': '../test/specs/',
        'text': '../lib/require/text',
        'durandal': 'durandal/js',
        'plugins' : 'plugins/js',
        'transitions' : 'transitions/js',
        'knockout': '../lib/knockout/knockout-2.3.0',
        'jquery': '../lib/jquery/jquery-1.9.1'
    }

For the HTML Starter Kit, with the test directory copied into the top-level directory at the same level as lib, css, and app, you only have to change three of them:

        'durandal': '../lib/durandal/js',
        'plugins' : '../lib/durandal/js/plugins',
        'transitions' : '/lib/durandal/js/transitions',

In general, you just need to find the durandal, plugins, and transitions directories and set the paths appropriately.

It's also helpful to add a path to the app directory where your code will live:

        'app': '../app',

You can test your paths by removing the existing test modules from test/specs (which will no longer work, since they are for Durandal's internal testing) and replacing them with a new, dummy test module such as:

define(['viewmodels/flickr'], function (flickr) {
    describe('', function(){
        it('returns true', function () {
            expect(true).toBe(true);
        });
    });
});

This sets up testing for the flickr module that ships with the HTML Starter Kit. If you're using some other setup, you'll need a different test. But this shows how it's done. It doesn't test every path, but since the flickr module uses the durandal and plugin paths, it tells you whether you're on the right track.

To run the test:

$ phantomjs spec.js

You'll know that you don't have the paths set correctly if you get a error like the fullowing, which leads to a hang of PhantomJS:

Running spec files: specs/mytest.spec
Error: Script error
http://requirejs.org/docs/errors.html#scripterror

  file:///Users/garyrob/Source/Durandal%20Projects/HTML%20StarterKit%20(Durandal%202.0)%20Exp%202/lib/require/require.js:32
  file:///Users/garyrob/Source/Durandal%20Projects/HTML%20StarterKit%20(Durandal%202.0)%20Exp%202/lib/require/require.js:12 in C
  file:///Users/garyrob/Source/Durandal%20Projects/HTML%20StarterKit%20(Durandal%202.0)%20Exp%202/lib/require/require.js:29

If all is well, you should see something like:

    Running spec files: specs/mytest.spec
    Starting...

    Finished
    -----------------
    1 spec, 0 failures in 0.002s.

And you'll be ready to unit test your new Durandal project!

October 11, 2013 in Durandal | Permalink | Comments (0)