I've always had problems with JavaScript, because the lack of tooling, no good source for documentation and the most advanced way of debugging being alert. It has become easier over the years with jQuery and Firebug, but being used to C# I'm still a bit lost when it comes to JavaScript. I was recently required to write some validation logic in JavaScript, and to make sure that I was on track the whole time, I adopted TDD in JavaScript with QUnit.
QUnit
Writing tests for JavaScript is actually much easier than unit testing C# code. You have so much more freedom in a dynamically typed language that makes it easier to write tests that will not pass, such as code in a statically typed language would not compile.
Getting started
Download jQuery, qunit.js and qunit.css and include them in an HTML document that will be host of your test suite.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Required field validation</title>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="qunit.js"></script>
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
<!-- SYSTEM UNDER TEST -->
<script type="text/javascript" src="Validation.js"></script>
<script type="text/javascript">
$(document).ready(function () {
/* TESTS GO HERE */
});
</script>
</head>
<body>
<!-- QUNIT REQUIRED HTML -->
<h1 id="qunit-header">Required field validation</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<!-- TEST STRUCTURE -->
<div id="test-container" style="display: none">
</div>
</body>
</html>
Keywords
You write your tests in the HTML document that you've created, and you use different HTML documents to divide your test suite in sections as it grows. My first test looks like this.
module("Validate on blur()");
test("Should validate required field as false when input value is empty", function() {
expect(1);
/* Initialize the validation */
heartbeat.initialize();
/* Select the required 'Name' field and execute blur() event */
$('#Name').blur();
equals($('#name-field').data('isValid'), false, 'Expected the field to be marked as invalid on blur()');
});
- module([string] heading) - A way to group tests together under a common heading
- test([string] name, function()) - The name of the test and the test code
- expect(1) - tells the test runner that I will use 1 assert
- equals([obj] actual, [obj] expecting, [string] message) - compares actual object with expecting object and fails if they are not equal. The message describes the failing condition.
- ok([boolean] condition) - though not present here, you can use the ok method instead of equals if you want to check that a condition is true.
It runs on the following HTML part.
<div id="name-field" class="field name required"> <label for="Name">Your name</label> <input id="Name" name="Name" type="text" value="" /> </div>
The beautiful thing about this is that I can write this test and get a red result without having implemented the actual validation logic yet. So, I implement the logic to make the test green and in my browser it looks like this.

One test executed successfully!
Setup and Teardown
Using the same HTML structure for all tests in the test suite is however not a good idea, because it will accuire state that will effectivly affect all other tests in the test suite. This means that we will have to recreate the HTML structure for every test run.
/* SETUP / TEARDOWN */
QUnit.testStart = function (name) {
$('#test-container').append('<div id="name-field" class="field name required"><label for="Name">Your name</label><input id="Name" name="Name" type="text" value="" /></div>');
};
QUnit.testDone = function (name, failures, total) {
$('#test-container').empty();
}
/* ************* */
There is no longer any reason not to unit test your JavaScript. You can download the whole example from here.
This post will describe how tests are setup within
Above is the result of
For every test you write you close your test suite closer to the system under test. This will make maintenance harder, because if you change any code in your SUT, you will definitely break some tests. This anti-pattern is called "the fragile test". The conclusion here is that you should use a coverage tool to make sure that you test the right things, and you should focus your testing where it is needed the most. Even with a very small amount of tests and a thought through test strategy you will reach 91% coverage without any tears (except those of joy). I will get back to 