QUnit – Unit Testing made easy for JavaScript

Are you test-infected?  Learned already how to grow your server-side apps using unit testing and want to do the same with client (HTML) layer? Search no more! QUnit to the rescue!

289

QUnit is a JavaScript library that helps you with tests specification, run and diagnostics. Firstly, you have to include qunit library and your tests in an html file:

<html>
<head>
<link rel="stylesheet" href="/resources/qunit.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="/resources/qunit.js"></script>
<script src="/resources/tests.js"></script>
</body>
</html>

Then you can start writing your tests, the simplest one, taken from documentation:

test( "hello test", function() {
ok( 1 == "1", "Passed!" );
});

As you can see:
  • syntax for new tests definition is very minimal, just test(name, function)
  • qunit is shipped with basic assert like functions: ok(), equal(), …
  • order of predicate and message is better than in JUnit 🙂

The next step in QUnit knowledge is to master asynchronous tests. I've seen many nonsense "sleep()" function implementations (hogging CPU power for a loop), properly used setTimeout() is the answer here. asyncTest() helps you with creating such tests that are time-related, an example:

asyncTest("zapChannel() basic test", function() {
    equal(MediaPlayer.zapChannel(2), 0, "0 code means operation succeded")
    // Check after 2s if there's confirmation signal of stream visibility
    setTimeout(function () {
        console.log("zapChannel() - check proper event presence")
        var ev = MediaPlayer.getEvent()
        ok(ev, "event data set")
        start();
    }, 2000)
}

I've bolded important parts:

  • asyncTests() starts test that will include asycnhronous parts
  • setTimeout() the corrent way for sleep() implementation
  • start() tells QUnit to continue, without that test won't finish properly

As you can see if there's an exception inside getEvent() call the start() call won't be called at all. So I've prepared a wrapper for setTimeout() that allows to finish the test and continue properly to the end of test suite:

function delayTest(fn, milliseconds) {
    setTimeout(function () {
        try {
            fn()
        }
        catch (e) {
            msg = e + ": " + e.stack
            console.log(msg)
            ok(0, msg)
        }
        start()
    }, milliseconds)
}

If you use above call instead of setTimeout() your test suite will terminate properly even for exception inside tested method.

And last, but not least: if you want to use ok() call in production code when qunit is not deployed you can use the following workaround:

/* allow ok() assertions even if qunit is not loaded */
if (!isFunction(ok)) {
    function ok(condition, msg) {
        if (!condition) {
            console.log(msg)
            alert(msg)
        }
    }
}

Have a great TDD JavaScript development in new 2014!

This entry was posted in en and tagged , . Bookmark the permalink.