Curse you, QUnit

| Comments (1) | Software
I've been writing some JavaScript lately and figured unit testing might be a good idea. I'm using JQuery, so QUnit seemed appropriate. By and large it seems pretty solid, but I recently discovered something annoying. I was working on a test suite in which I first created and stored an object and then retrieved it. Everything was going along swimmingly and then I messed something up in the retrieve code. No problem, that's the kind of thing unit testing is supposed to catch, so I fixed the bug, but the retrieve still didn't work.

A little debugging revealed the proximal cause. The store returns a new object identifier (actually a sequence number), which I was using to retrieve the object. But when I went to get the object, the identifier was 0; it had never been set. For a while I thought I was just missing something important about JavaScript variable scoping, but after a bunch of debugging I uncovered the real problem: when you have a set of QUnit tests and one of them fails, QUnit remembers. The next time you run the test suite, it helpfully runs the tests that failed first. So, consider the following code:

       module("Test");
       asyncTest("Test 1", function(){
           d = new Date();
           console.log("Test 1: " + d);
           ok(true);   // report success
           start();
         });
       
       asyncTest("Test 2", function(){
           d = new Date();
           console.log("Test 2: "+d);
           ok(false);  // report failure
           start();
         });

The first time you run the test suite, Test 1 runs first (and succeeds) and then Test 2 runs (and then fails). However, the next time, Test 2 runs first, then Test 1. In a real scenario where Test 2 depends on Test 1, Test 2 will fail again, which means it will run first again, ad infinitum.

This seems like a good idea from some perspective, I guess: why should you have to wade through all the tests that work in order to retest the one that failed? Unfortunately, if the tests need to be run in a specific order then everything goes to hell.

I don't see this feature in the documentation; I found it by source code inspection. I suppose it's probably in there somewhere, though. Anyway, there's a way to force the tests to run in order. You just do: QUnit.config.reorder = false;

Outstanding!

P.S. Mrs. G tells me that unit tests are supposed to be order independent and so I should make any operations that need to run in sequence a single test. That's one way to do things, I guess, but I don't really want my software silently forcing it on me. `

1 Comments

Around 2006 or so someone did a mashup of Queen and the rap group G-Unit under the name "Q-Unit". The first thing I thought when I saw this headline in my reader was "I wonder why he didn't like the album, it was pretty good"... I can decide if this means I'm less of or more of a geek than I thought =)

Leave a comment