MooTest: A simple test unit for javascript and mootools

MooTest is a simple test unit system for Javascript based on the MooTools 1.2 libraries.

Table of Contents

1   References

Main reference for MooTest is, obviously, the MooTest site. Secondarily, in the distribution you can find the MooTest API documentation in the "apidoc" folder.

2   Requirements

MooTest requires the MooTools library version 1.2 and the Asset plugin to work. All software modules are included in this distribution.

3   Compatibility

Up to now, the software is in alpha stage, has been tested mainly on Firefox 3 and passed the unit tests also for Internet Explorer 6 and Safari 3.1.2.

4   How to use it: a simple example

This is a simple walkthrough about using the MooTest system.

4.1   Write the class to test

First of all, we write a simple class to test in the file sumclass.js:

var SumClass({
    initialize: function(value1, value2) {
        this.value1 = value1;
        this.value2 = value2;
    },
    getSum: function() {
        return this.value1 + this.value2;
    }
});

Notice that we write the body of the class methods to test in the first step because this is not a real program, but just an example. It should be done, instead, after the following step, according to various software engineering methods, like Agile Programming.

4.2   Write the test classes

Then, we create a Test Block. A Test Block is any entity which contains tests. The simplest Test Block is the Test Set, a simple collection of test methods. We write it in a file called testsumclass.js:

var testBlock = new MooTest.TestSet({
    sumIsGreaterThenOperand: function() {
        var v1 = Math.random(), v2 = Math.random();
        var inst = new SumClass(v1, v2);
        this.assertGreater(inst.getSum(), v1,
            'sum is not greater than first operand');
        this.assertGreater(inst.getSum(), v2,
            'sum is not greater than second operand');
    },
    sumIsEqualToOperandSum: function() {
        var v1 = Math.random(), v2 = Math.random();
        var inst = new SumClass(v1, v2);
        this.assertEquals(inst.getSum(), v1 + v2,
            'sum is not equal to the operand sum');
    }
});
testBlock.additionalJavascripts = [
    [ 'sumclass.js' ]
];

Notice well the additionalJavascripts piece at the end. It is a list of additional javascripts needed for the test, and it tipically contains the javascript of the library we are testing. It is expressed as an array of paths, where each one of them is array of path components relative to the test path. E.g., if we would have had also a 'common.js' script in the parent directory to load, we would have used the following code:

testBlock.additionalJavascripts = [
    [ 'sumclass.js' ],
    [ '..', 'common.js' ]
];

4.3   Run the tests

To run the test you have to open the testpage.html file in your browser and fill in the fields you see: "Tests javascript file" with the full path of the testsumclass.js file, and "Test block" with the name of the variable containing our Test Block, in this case, testBlock, then click "Run".

Upon clicking "Run", the tests will be performed, and the results will appear. A short summary line will be displayed at the very bottom.

5   Test suites

A test suite is a container of Test Sets or of other test suites. Test suites are useful for two reasons:

  • They allow you to better organize your test code in levels and groups.
  • Through test suites, you can make different selections of test groups according to the functionality you want to test. E.g.: let's say you're making a rich GUI in Javascript. You have a test suite which tests the utility classes, one which tests the model classes, and another which tests the network classes. You can have a fullTests test suite which contains all the three blocks, a modelTests which contains the tests of the utility classes and of the model classes, and a networkTests which contains the tests of the utility classes and of the model classes.

A test suite is very easy to declare, and after that, you use it just like any other Test Set (in the example below, firstTestSet and secondTestSet are both Test Sets):

var testSuite = new MooTest.Suite({
    firstBlock: firstTestSet,
    secondblock: secondTestSet
});

6   Test runners

A test runner is the class which runs the tests contained in a Test Block, either TestSet or Suite, and must be derived from MooTest.TestRunner. The instances of this class informs about the test run through events about the tests and their income. Here it is a sample class which just collects the results of the tests. Look at the API documentation for a more detailed description:

var TestRunCollector = new Class({
    Extends: MooTest.Runner,

    initialize: function() {
        this.addEvent('init', this._init);
        this.addEvent('testStart', this._testStart);
        this.addEvent('testPassed', this._testPassed);
        this.addEvent('testFailed', this._testsFailed);
    },

    _init: function() {
        this.testsTaken = [];
        this.testsPassed = [];
        this.testsFailed = [];
        this.testsCompleted = [];
    },

    _testStart: function(name) {
        this.testsTaken.push({name: name});
    },

    _testPassed: function(name) {
        this.testsPassed.push({name: name});
        this.testsCompleted.push({name: name});
    },

    _testsFailed: function(name, message, source, line, stack) {
        this.testsFailed.push({name: name, message: message, source: source, line: line, stack: stack});
        this.testsCompleted.push({name: name});
    }
});