Testing server side javascript with qunit and junit

Introduction

This tutorial aims at testing server side javascript on Alfresco and Alfresco Share through BDD test for Behavioral Development Driven.

Such a test looks like the following:

pavlov.specify("AutoComplete Test Set", function() {
    describe("Should be able to automatically update meta data ...", function() {

        var doc;

        function fail(msg) {
            $Logger.debug(msg);
            assert(true).equals(false);
        };

        before(function() {
        });

        after(function() {
        });

        it("for MarchesPublics:ECategory type", function() {
            fail("Not yet implemented");
        });

        it("for MarchesPublics:EPayment type", function() {
            fail("Not yet implemented");
        });

        it("for MarchesPublics:EOrganization type", function() {
            fail("Not yet implemented");
        });

    });
});

Development process

Usual way

I won't detail here why writing tests is important. Such a subject is already well documented.

Code Example

Just know a developer always write some tests to check its code, generally of the form :

print(new Date());
print("Start");

r = some code

print("Result = " + r)
print("End")

+ and -

Drawbacks

This approach has several drawbacks:

  • No level: logs are always displayed,
  • When the code is ok, logs are removed : need to rewrite them for the next debug iteration,
  • No IDE integration,
  • No CI integration,
  • No unit test,
  • No history.

An improved way

Imagine a $Logger object is available. The same code than before could be written the following way:

$Logger.debug("Start");

r = some code

$Logger.debug("End");

+ and -

Advantages

  • $Logger automatically adapts itself to context, so messages are displayed in a console for interactive development phase or not if code is executed in production
  • logs are automatically prefixed by date and time
  • logs are structured with levels so it is possible to selectively trace them to only have the interesting level

Drawbacks

  • Still no IDE integration,
  • No CI integration,
  • No unit test,
  • No history

A more improved way

Logs are very important but aren't tests. Numerous frameworks exist to develop some tests. They generally provide a way to automate tests by extracting information from source code so they know the methods to tests.

jQUery uses a framework called qUnit. This one enables the developer to write unit tests the following way:

QUnit.test( "ok test", function( assert ) {
    assert.ok( true, "true succeeds" );
    assert.ok( "non-empty", "non-empty string succeeds" );
    assert.ok( false, "false fails" );
    assert.ok( 0, "0 fails" );
    assert.ok( NaN, "NaN fails" );
    assert.ok( "", "empty string fails" );
    assert.ok( null, "null fails" );
    assert.ok( undefined, "undefined fails" );
});

This approach is interesting but lacks some kind of glue to make this more functional and user oriented. BDD or Behavior Driven Development brings this lacking part and provides the following sugar:

pavlov.specify("AutoComplete Test Set", function() {
    describe("Should be able to automatically update meta data ...", function() {

        var doc;

        function fail(msg) {
            $Logger.debug(msg);
            assert(true).equals(false);
        };

        before(function() {
        });

        after(function() {
        });

        it("for MarchesPublics:ECategory type", function() {
            fail("Not yet implemented);
        });

        it("for MarchesPublics:EPayment type", function() {
            fail("Not yet implemented);
        });

        it("for MarchesPublics:EOrganization type", function() {
            fail("Not yet implemented);
        });

    });
});

+ and -

Advantages

These tests may be written by a user, the developer implementing them to make them succeed. Results look like this:

Tests may be done in a continuous integration build but results and historized (at least in an interesting and usable way).

Drawbacks

  • No IDE integration
  • No history

The graal

We only lack 2 features:

  • IDE integration
  • Test History

IDE integration

IDE integration simply means to have a way to play tests from the IDE. It may be done through the use of external scripts in SIDE for example, based on Eclipse:

Please note:

  • Tests are launched from the menu
  • Output is done into the Alfresco log file as you can see at the bottom. Logs are also written in xml unit.

A more tight integration could be done through the use of jUnit, widely supported in the IDE's world. It should be interesting to integrate our server side js tests as jUnit tests so we can benefit from IDE views. It has not been done yet, but it's on the roadmap :-)

History

History must be played at each build and graph should display results in a historized view so developers and users may see how succeeding tests evolve :

Ressources