TDD in Javascript with QUnit
These days you'd be hard pressed to find a web application that isn't using JQuery, Prototype, or YUI. Over the last few months I've had several conversations with fellow developers about how to test applications using these frameworks.
Fortunately each of these frameworks includes a unit test runner. In this article I dive into QUnit, the test harness for JQuery based web applications.
Technologies
In this example I'll be using the following technologies:
- JQuery 1.2.6
- QUnit - I used the current trunk version as of 1/9/2008
QUnit TDD Workflow
In QUnit, each test "class" is a single HTML file. You write a <script>
block inside this file that contains your unit test code. Consequently, the TDD workflow looks like this:
- Create a QUnit HTML file
- Write a test function in the file
- Load the HTML file in your browser (using a
file:///
path, no web server required - The test function should run, and fail
- Write Javascript code to make the test pass
- Refactor
- Repeat
Reloading the HTML file in your browser becomes natural after a while. It's the equivalent of running a JUnit test individually in your IDE. And if you use Firebug you can debug the js code while the test runs if necessary.
Example
QUnit HTML file: test1.html
<html>
<head>
<title>Group Tests</title>
<!-- these 2 lines will be the same in each of your QUnit HTML files -->
<script language="javascript" src="../../main/webapp/js/jquery-1.2.6.min.js"
type="application/javascript"></script>
<link media="screen" href="testsuite.css" type="text/css" rel="stylesheet"/>
<!-- this file contains the js file under test -->
<script language="javascript" src="../../main/webapp/js/group.js"
type="application/javascript"></script>
<!-- your test functions go in this block -->
<script language="javascript" type="application/javascript">
$(document).ready(function() {
test("constructor hides div", function() {
var controller = new CreateGroupController('create-group');
equals($("#create-group").css("display"), "none", "Element should be hidden");
});
test("shows div when told to", function() {
var controller = new CreateGroupController('create-group');
controller.show();
equals($("#create-group").css("display"), "block", "Element should be visible");
});
});
</script>
</head>
<body>
<h1>Group Tests</h1>
<!-- these are boilerplate elements that qunit requires -->
<h2 id="banner"></h2>
<ol id="tests"></ol>
<div id="results"></div>
<div id="main"></div>
<!-- this is the div we're going to show/hide in our test -->
<div id="create-group">
<form action=""></form>
</div>
<!-- I put this at the bottom of the file to workaround an issue in HTMLUnit, which I use to
automate running the tests on my Continuous Integration server -->
<script language="javascript" src="testrunner.js" type="application/javascript"></script>
</body>
</html>
Output in Browser
When you run this test, you'll see output like this:
A failed test will look like this:
Conclusion
This is a very basic overview of how to use QUnit to test drive your Javascript development. In my next entry I'll explain how to automate your tests using JUnit and HTMLUnit.