Unit Testing your Javascript Code.

As it’s been a while since my last “useful” posting I will bite the bullet now and therefore I will try to point you to a very easily overseen part of unit testing - the Java Script part.

Unit Test and Javascript ? Oh yes - we are living in the Web 2.0 (or even 3.0?) century and most applications do have huge parts which are written in Javascript. And for sure you need to test these part’s also - especially if you are following the eXtreme way of programming.

There are some tools around doing this, most popular is probably jsunit but today I want to focus on Crosscheck - an open source, java based test framework for your javascript code. Crosscheck’s huge advantage is that you do not need any browser - it simulates them so it can be run from commandline. The upside is - it works really nice, integrates smooth with Cruisecontrol and tests on different browsers. But for sure there is a downside - and this is - it works without the browsers and simulates them.
Unfortunatly simulating a browser can never be perfect, so you will have tests which will give wrong results - either the tests claim that it should run, but in real world it won’t or vice versa. Also some popular libraries like YUI are not yet supported and throw errors - but AFAIK thy are working on it - let’s hope the best.

The best place for all infos around Crosscheck is the developer site.

Now let’s start from the scratch - point your browser to ‘thefrontside’ and download the file. Make sure that you download the compiled version and not the source (*-sc*) version as these won’t work for you.
Unzip, and copy the file ‘crosscheck.jar” where ever you want to have it.

Now test if it’s working:

crosscheck$ java -jar crosscheck.jar

must print something like

Please specify at least one test file or directory.
Usage: java -jar crosscheck.jar [options] [test-file | test-directory]*

If not - install the latest JRE on your machine, and make sure that JAVA_HOME is set correct and the “java” binary is in your PATH.

For easier usage on the commandline and later in cruisecontrol we should create a shell script to wrap this call - so let’s do it. It could look like this:

java -jar crosscheck/crosscheck.jar $@

Also don’t forget to chmod +x the .sh file.

Creating our first Testfile is quite easy. Create a directory “js” in your “tests” directory whereever you also have your unit tests - simply create the directory parallel to “unit” directory and there we add a file called “demo.jst” with the following content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
crosscheck.addTest({
 
    setup: function()
    {
 
        //crosscheck.load("../out/js_source/filter.js");
    },
 
    /**
        dummy test example
    */
    "test if something does something else": function ()
    {
         assertEquals("0,- €", "0,- €");
    }
 
})

Now let’s have a look if it works:

$ crosscheck.sh demo.jst

And you should get something like this:

Running tests in environment: Mozilla 1.7 (Firefox 1.0)

0 tests: 0 Ok, 0 failed, 0 errored.

Running tests in environment: Mozilla 1.8 (Firefox 1.5)

0 tests: 0 Ok, 0 failed, 0 errored.

Running tests in environment: Internet Explorer 6

0 tests: 0 Ok, 0 failed, 0 errored.

So far so good, how does the integration with cruisecontrol now work ? Actually very very simple - this is why I have chosen to use crosscheck - it can export the junit format. Running crosscheck with -xml command produces JUnit files:

crosscheck.sh -xml=report js/

So this means you have to update your build.xml and add a new section for testing jScript - it could look like this:

<target name=”testjs” description=”Run the Javascript tests”>
<exec dir=”${project.srcdir}/tests” executable=”crosscheck.sh” failonerror=”false”>
<arg line=”-xml=${project.logdir}” />
</exec>
</target>

or whatever your config.xml / build.xml philosophie is.

I hope I made mayself clear - after reading this there should be no excuse for NOT testing Javascript.

And last but not least a big THANK YOU to the guys at Frontside, Charles Lowell and Jason Wadsworth for the good work!