Some QUnit tips

June 21st, 2008

After creating several tests for key functionalities of our product, I thought I might share some things I’ve learned – the hard way – about QUnit.

Run the tests on every browser you have

Obvious, if you think about it, but for some reason I was just running my tests on FF2. Then when I tested the real app in IE I got those nasty errors, which start the usual TDD programmer reaction “but I got tests for those, and they all pass”. Not on IE, friend. Turned on that some places that I used things like

for(var opt in select.options)..

(unsurprisingly) had a different behavior on FF and IE.

equals() is “inverted”

As any long time user of jUnit and then NUnit, I was used to use equals( expected, actual ). In QUnit, for some reason, this is inverted.

While you’re on it, add an assertion message to ok() and equals(). Also, differently than Nunit, this should be a sentence that makes sense when all is green. If it’s red, you will infer easily what went wrong.

Put your html on the div#main

But don’t expect to see changes there. The div#main on the html page is reseted for every test. Basically what happens is that QUnit saves the initial html inside that div, and restores it after each run. QUnit also resets ajax configurations and global (jquery) events.

Mock as you wish

I’m not a true fan of mocking, and I see it’s being overused nowadays. After reading Kent Beck’s post on the XP list, I realized I wasn’t wrong on my gut feelings. Testing the interactions among the real classes is better, mock what is costly and what is outside your control. For JS testing these can be several things…

In my case I mock jQuery’s ajax calls, by simply doing this:

jQuery.ajax(opts) = function(opts) {
    recordedAjaxOpts = opts;
}

So, on my test I can get the recordedAjaxOpts, assert what was passed to it, invoke success/error if I want.

Separated files

I’d suggest that you create a html per main js file, which could load more than one test.js files, though. I started by keeping one file, but that is just slow.

If a test is failing, double click it on QUnit, and it will focus on that one only (beautiful!).

Categories: jQuery | Top Of Page | 4 Comments » |

4 Responses to “Some QUnit tips”

Dmitriy Nagirnyak Says:

Just curious, why didn’t you want to use Selenuim?

What were the reasons to choose QUnit instead of JsUnit, Selenium or anything else?

Thanks.

Paul Cowan Says:

Does anyone know how I would call QUnit from CruiseControl server?

It would be good to get the test ran as part of the CI build.

hammett Says:

@Paul, indeed. havent figured out a way to do that, though.

@Dmitriy, I wanted js test cases, not integration, end to end test. Selenium and watir/n are out.

I considered the jsunit, but I dislike their test runner.

I also find that there’s a lot of _very_ talented people around jquery, so I was more inclined to pick it.

James Cooper Says:

Great post. I was looking for the jQuery.ajax() mocking tip.

Regarding CI with QUnit, it’s possible to write a short JUnit test that runs your QUnit .html files using HTMLUnit. I wrote a blog entry about how to do that here: http://www.bitmechanic.com/blog/?p=24

Leave a Reply