2009-12-06

A minimalist unit test framework for JavaScript

When I started doing some serious JavaScript programming for a project based on Mozilla's XULRunner, I figured it would be easy to find a suitable unit testing frameworks -- something similar to JUnit, only for JavaScript. After some searching, I found a number of frameworks. Every one, however, had too many features.  Most relied on browser features of some sort that XULRunner just doesn't have. No doubt if I were doing web-site development, I'd be only too thankful. But I'm not and I needed something.

As a result, I created a very very simple framework that uses only standard ECMA script. The framework is called "xulUnit", at the moment, but it should be emphasized that it really has nothing to do with XUL except for being compatible with XULRunner.

An example


Once the framework is loaded, one adds a set of test objects. The function xulUnit.addTest accomplishes this. This function takes two arguments. One is the name of the test and the second is the test object. Below we add a test object that tests the basic functionality of the framework.
This is file testXulUnitItself.js This test object contains four test methods. (Test method names must start with the letters "test".) If we run the framework at this point, we get as output.
Now this is not pretty, but then it's not meant to be. You can see that the four test methods are run, bracketed by setUp and tearDown. Each test has one of three results.
  • Pass. If it returned normally.
  • Fail. If some assertion fails.
  • Error. If an exception is thrown.
A summary of how many tests had each result is printed at the end.

A complete example

Now let's see a complete example of using xulUnit.

This is file xulUnit.html
  • Line 5 loads the framework. (The file xulUnit.js can be found at the end of this article.)
  • Line 7 loads the test file we saw earlier. 
  • Lines 10-14 redefine xulUnit's xulUnit.printlnfunction. All output from xulUnit uses this one function. The default definition uses JavaScript's dump function, which doesn't work well in my browser. This redefinition sends output to the html document. Another useful redefinition is
  • Finally line 20 runs the tests.
The API

The API is summarized as follows
  • xulUnit.addTest( testName : string, testObject : Object ) -- add a test object.
  • xulUnit.runTestsNow() --  run all tests that have been added since the last time it was called.
  • xulUnit.assertTrue( q : boolean, message : string ) -- fail unless q is true. (Second argument is optional.)
  • xulUnit.assertFalse( q : boolean, message : string ) -- fail unless q is false. (Second argument is optional.)
  • xulUnit.assertNull( q : boolean, message : string ) -- fail unless q is null. (Second argument is optional.)
  • xulUnit.assertNotNull( q : boolean, message : string ) -- fail unless q is not null. (Second argument is optional.)
  • xulUnit.assertSame( expected, actual, message : string ) -- fail unless expected===actual. (Third argument is optional.)
  • xulUnit.assertEquals( expected, actual, message : string ) -- fail unless expected==actual. (Third argument is optional.)
Known problems.
  • Stack traces only work in Mozilla based implementations of JavaScript.

Here is the framework.
This is file xulUnit.js