BYTE-force columns
Company news, team and friends.

Using jqUnit for JavaScript unit testing

Recently I was improving our on-demand script loader, and decided that it would be great to do it in test-driven way. After all, this is clearly a piece of code that should be tested automatically. I've started with jsUnit, just because it looks like obvious choice. Very quickly I found that it can't test modern JS code, because of "wrong" ideology. As in all traditional xUnits it simply executes one test function after another one ends, and this doesn't allow you to test various async requests, setIntervals and so on.

Help is coming from jqUnit. This library is based on jQuery's testrunner – the testing framework for jQuery. Unfortunately, I've not found any official page about testrunner itself. There are only links to the source code, or to the running test suite.

jqUnit uses a bit different testing logic. I will try to describe it as I understood it for myself:

  1. All tests on the page are executed exactly in the sequence you wrote them.
  2. If you want to wait for async request to finish, you can use stop() method. When it would occur, use start() to continue test run.
  3. In each test you specify number of test assertions that should be executed. If your test executes more or less assertions it fails.

Here is the simple example of the test:

jqUnit.module('Load');    
jqUnit.test('Load module1.js', function(){
jqUnit.expect( 3 );// expect total of 3 assertion
jqUnit.equals( typeof Module1, 'undefined', "Module1 is not loaded." );
jqUnit.stop();
SDF.Using( "/test/loader/module1.js", function() {
jqUnit.assertNotUndefined( "Module1 loaded", Module1 );
jqUnit.assertEquals( "Module1 loaded", Module1.name, "Module1" );
jqUnit.start();
});
});

Here we define module "Load", then test named "Load module1.js". In the test we expect 3 assertions. If script in the SDF.Using block would not be executed, then two assertions inside of it won't happen and total number of performed assertions would be 1 (instead of 3). Script in the SDF.Using block could be executed asynchronously. So we stop() test execution before it and start() it at the end of the block.

To shorten usage of jqUnit you can use "with" keyword:

with( jqUnit ){
module( 'Load' );
test( ...
}

API of jqUnit:

  • module( String name )
    Call on start of module test to prepend name to all tests.
  • test( String name, Function callback, Boolean nowait )
    Defines test with specified name.
  • expect( int n )
    Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
  • stop()
    Halt execution of further tests, while we wait for expect(n) tests to finish.
  • start()
    Resume execution of further tests.
  • ok( Boolean v, String msg )
    Asserts true. Example:
    ok( $("a").size() > 5, "There must be at least 5 anchors" );
  • equals( Object actual, Object expected, String msg )
    Checks that the first two arguments are equal, with an optional message. Prints out both expected and actual values on failure. Example:
    equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
  • isSet( Array a, Array b, String msg )
    Asserts that two arrays are the same.
  • isObj( Object a, Object b, String msg )
    Asserts that two objects are equivalent.
  • q( String id[, ...] )
    Returns an array of elements with the given IDs. Example:
    q("main", "foo", "bar")
    results in [<div id="main">, <span id="foo">, <input id="bar">]
  • t( String msg, String query, Array ids )
    Asserts that a selection matches the given IDs.
    Example: t("Check for something", "a", ["foo", "baar"]);
    returns true if "a" return two elements with the IDs 'foo' and 'baar'

For compatiblity with jsUnit:

  • assertEquals( String msg, Object expected, Object actual )
  • assertTrue( String msg, Boolean v )
  • assertFalse( String msg, Boolean v )
  • assertUndefined( String msg, Object o )
  • assertNotUndefined( String msg, Object o )
  • assertNull( String msg, Object o )
  • assertNotNull( String msg, Object o )

For more information on jqUnit see its page on Google Code.


Posted Mar 26 2008, 05:23 AM by Andrew Mayorov

Comments

Links for 2009-02-17 at hocuspokus wrote Links for&nbsp;2009-02-17 at hocuspokus
on 02-17-2009 15:05

Pingback from  Links for 2009-02-17 at hocuspokus

Copyright ©2004-2009 BYTE-force
Powered by Community Server (Non-Commercial Edition), by Telligent Systems