Though a friend of mine and myself lately started again with continuous integration projects for the company’s we work for, and we both like test driven development, if it is no overkill, I came across Qunit which is a library provided by jQuery for Unittesting javascript. Until last week I did not even know something like this existed for Javascript, but I am very happy that I came across this . Because I think unittests are a good way to assure that your code works as expected, I´d like to show you how to setup and write jQuery unittests.
First of all you will need to download the following two files from the jQuery Api – Docs Website:
Afterwards you will need to create a new html file with the following code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" href="core/qunit.css" type="text/css"/>
<script src="http://code.jquery.com/jquery-latest.js"> </script>
<script type="text/javascript" src="core/qunit.js"></script>
<script type="text/javascript">
// --- Unittest Code goes here ---
</script>
</head>
<body>
<h1 id="qunit-header">QUnit example</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests">
</ol>
</body>
</html>
This Html file will be the page we can view the testresults on.
In this tutorial I only like to give you a brief overview of what can be done how, because most of you will be familiar with writing unittests at other languages, and in the case of javascript and jQuery this will be almost the same.
So lets go write our first unittest:
$(document).ready(function(){
module("Basic Unit Test");
test("Sample test", function()
{
expect(1);
equals(divide(4,2),
2,
'Expected 2 as the result, result was: ' + divide(4,2));
});
});
If you now open the the html page in your prefered browser you will see something like this:
Your unittest failes, just like one might have expected because we never implemented the divide method into our code. But lets go step by step. You might have recognized several different parts of code in the js – snippet that need a little explanation.
First of all we have a line “module(“Basic Unit Test”);”. By adding this we are able to separate the modules we want to test visually on the test page. If you take a look on that page after running the tests you will read “1. Basic Unit Test module: Sample test (1, 0, 1)” at the moment. So the string we have set by adding “module(“Basic Unit Test”);” to our code is displayed there as well as some more information we have provided by the lines that followed this one.
Next line we have added so far was “test(“Sample test”, function(){});”. This is basically the declaration of a single test that you run. The first parameter is a String that simply gives the test a name(“1. Basic Unit Test module: Sample test (1, 0, 1)”), the second one is a callback function that is called the moment we run the test by loading the page. Lets go on analyzing the code we just tested.
Next thing you might have recognized is “expect(1);”, this is a simple declaration how many assertions we expect at this single test. At the moment we run only one so this is set to one. If we had set this one to two for instance, the result of our test would be that not one assertion has failed but two, because in that case we would also have forgotten to implement the second assertion.
Lets move on to the last line we just implemented “equals(divide(4,2),2,’Expected 2 as the result, result was: ‘ + divide(4,2));”. This is the actual assertion we wanted to make, just to make sure that the method “divide” works properly and returns the mathematical correct result. The Qunit method equals takes three parameters. The first one and the second one are the ones compared, the third is a String, a message you might want to print out. This message is handled by the Qunit.log() method I will show you later.
Besides the method equals there are two more methods provided to you for testing. They are called “ok” and “same”. While “ok” is a simple Boolean check and for this only takes two parameters, the Boolean value that has to be true in order to not make the test fail, and a message, the “same” method is kind of like equal. The only difference between those two is that equal only returns true if both, the first and the second parameter, are 100% equal ( like a === b), and same only compares the variables values vs. each other.
But let me give you some example code:
var arrayContainer = {a: 'firstElement'};
equals(arrayContainer, {a: 'firstElement'}, 'Will fail');
same(arrayContainer, {a: 'firstElement'}, 'Will pass');
After describing the basics to you we can now start to make our test working. This is quite easy just add the following to your code:
function divide(a,b)
{
return a / b;
}
Your unit test passed, congratulations. But if you are a little bit like me you are missing the message we added to the equals assertion in our test, it is not displayed anywhere at our page, and even if you look at the console there will be nothing. This is because the public method Qunit.log() was indeed declared in the class file, but no code that would display the messages has been implemented. To my mind this was because the developers of Qunit wanted it to be up to your decision whether or not you like to display them.
It is done really easy and in this tutorial I will show you how to display them in the console of the browser (though it has one), just add the following on top of the ready callback :
QUnit.log = function(result, message)
{
if (window.console && window.console.log)
{
window.console.log(result +' :: '+ message);
}
}
If you now reload the Unittest page, open up Firebug for instance (in prior), and switch to the console view of Firebug you will see this:
By now you should have the gear to develop some unittest for jQuery or any other javascript you use might in your project. I hope this tutorial has given you a good overview and a nice point to start from.
The following link provides a zip file with the summary of this tutorial:
jQunit-tutorial.zip





[...] This post was mentioned on Twitter by SwiftLizard, Codrops Team. Codrops Team said: Development with jQuery & Qunit http://www.swift-lizard.com/2009/11/24/test-driven-development-with-jquery-qunit/ [...]
Social comments and analytics for this post…
This post was mentioned on Twitter by SwiftLizard: New Blog post: http://www.swift-lizard.com/2009/11/24/test-driven-development-with-jquery-qunit/...
Nice contribution. Thanks.
Just thought you’d be interested to know that I have added you to my bookmarks You make valid points in a concise and pertinent fashion, I will read more of your stuff, thank you for your time. one of my articles hope u enjoy reading getting paid for surveys
[...] Development with jQuery & Qunit [...]
Hello, nice day! Your content is incredibly impressive. I never imagined that it was probable to accomplish something like that until after I checked out your content. You undoubtedly gave an incredible insight on how this kind of whole process functions. I’ll make sure to return for more information. Keep it up!
Hi,
Nice article there.
Got a couple of questions though still dangling in mind.
what if the javascript i want to unit test is inside a server page like jsp.
what is the standar practice to do? do i put the unit test inside that jsp or in another jsp?
if it’s in another jsp, how to access the dom objects of the target jsp from the unit test jsp?
this is the first time i came across the idea of unit testing a javascript. so i’m kind of confused about the deployment and mechanism.
Thanks and Best Regards,
abu3ammar.
Hi abu3ammar10,
to my mind unit testing is no meant for js within a single page but rather for js files providing methods to use for the page, so if you have any methods within a page you should exclude them to a external js file. In that case you should be able to unit test your js. For your other questions there is no standard answer for that, everyone has his or her own style. As far as I can tell the “normal” procedure is that unit tests include all the code needed for the test to succed, it is almost the same as a java unit test, even there one will provide the data needed.