Unittesting javascript with QUnit

Test-driven development has become fairly standard (although not everywhere, and tests aren't always written first). So, when we set out to build our applications and their features, we dutifully write our tests, run them everytime, yadda-yadda-yadda. Then, when we decide to add some javascript goodness to our web apps, so they feel like native apps, we ... sort of end up with giant js-files full of unmaintainable javascript badness.

Just like unit tests can drive your design decisions, and help you in keeping your C#/VB.NET/... code clean and maintainable, so can it be the case for javascript. But unit testing javascript is a little-known beast. However, you better get to know it, as javascript will become more and more prevalent. Either in your web applications or because WinJS and/or TypeScript became the next best thing. And who knows, the beast might turn out to be a cuddly panda.

As it turns out, unit testing your javascript is actually quite simple. I'm assuming that you are able to refactor ugly code, extract pieces of logic out of complex algorithms, and have some basic understanding of javascript (and its OO patterns).

So let's get started. I used QUnit because I have no experience with javascript unit testing and had to take any framework. But it appears to be quite popular.

To add QUnit to your project, all you need is two files: qunit.js and qunit.css. Of course, your javascript file:

function Television(brand) { 
      var brand = brand;       var channel = 1;            this.getBrand = function() {            return brand;       }            this.channelUp = function() {            channel++;       }            this.channelDown = function() {            channel--;       }            this.getChannel = function() {            return channel;       } }
Finally, you have to set up your tests. With QUnit, this is done by creating a webpage, referencing the QUnit files, adding two qunit-specific divs, and finally adding javascript to run your tests (either in the web page or in a separate javascript file). The webpage can be done in any way (ASP.NET, static HTML, etc.). For this simple example, I've just made a simple HTML file, containing the following:

<div id="qunit"></div> 
<div id="qunit-fixture"></div> <script src="./qunit-1.10.0.js"></script><br /> <script src="./codefile.js"></script><br /> <script><br>     test("Testing the brand name.", function() {<br>       var tv = new Television("Sony");<br>       equal(tv.getBrand(), "Sony", "The brand of our tv object must be Sony." );<br>     });<br>     <br>      test("Testing the initial channel.", function() {<br>           var tv = new Television("Sony");<br>           equal(tv.getChannel(), 1, "The initial channel must be one.");<br>      });<br>     <br>      test("Testing the channel up method.", function() {<br>           var tv = new Television("Sony");<br>           tv.channelUp();<br>           equal(tv.getChannel(), 2, "The channel must be two after calling channelUp.");<br>      });<br>     <br>      test("Testing the channel up method.", function() {<br>           var tv = new Television("Sony");<br>           tv.channelUp();<br>           tv.channelDown();<br>           equal(tv.getChannel(), 1, "The channel must be one after calling channelUp and then channelDown.");<br>      });<br></script><br /><br />
If you're familiar with 'traditional' unit testing frameworks (like NUnit), you should recognize the pattern. There are many other methods besides equal(), like notEqual(), throws(), start() and stop() for asynchronous calls, methods for callbacks, configuration, etc.

As you can see, getting started with javascript unit testing is actually very easy, and if you start working with it, it's a mystery why you've held this back for so long (thinking it was sort of complex). So start out with some simple and easy tests, and continue from there.

P.S.: there are a few alternatives like JsUnit (whose site seems to be down), Jasmine, Mocha and others. Also, once you start having some tests, you might want to look into setting this up in your Continuous Integration process (you are doing that right?). I don't have any experience with that, but just Google around and you'll find some resources.

Update 8/7/2013: There is now a project template for Visual Studio so you can quickly get set up for javascript unit testing. More info on Codebetter.com.