Testdriven development with JavaScript and QUnit
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.
<!-- 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.
/* 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 headingtest([string] name, function())
- The name of the test and the test codeexpect(1)
- tells the test runner that I will use 1 assertequals([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.
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.
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.