According to John Resig and Bear Bibeault
48% of JavaScript developement (see chapter 2, Secrets of the Java Script Ninja) do not test. The advantages of unit testing code and developing in a test driven approach have been well documented and don't need to be rehashed - suffice to say the arguments are equally applicable to JavaScript code. One popular approach to unit testing JavaScript is the QUnit framework. This framework was originally built to test JQuery and then evolved into a stand alone unit testing option for JavaScript in its own right. Let's consider an example.
Suppose we have an architecture where the Web Tier makes AJAX REST style requests to a server and gets back information about entities in JSON format.
It is probable that we will want to adapt the data that comes back into custom JavaScript objects that we can send on to various parts of the GUI.
To convert the data, we use something similar to the GOF Adapter pattern. We collate methods involved in adapting different entities and then place them all in an object literal as follows:
Note 1: Yes the above example is super simple. The only adaptation that is really happening is that the adpated name variable is made up from combining the first name with the last name that are in the JSON. The real world is obviously a more complicated place, but this simple adaptation example is enough to show how things hang together using QUnit.
Note 2: If you are wondering why I did not use a closure above, it is because there is no need for any state in these methods, hence there is no need to encapsulate any state. But again, in the real world you may not find it so easy to avoid state and if it comes you are better off encapsulating it using a closure.
var dublintech = dublintech || {}; // dataAdapter contains some functions to convert data. // Idea is this can map JSON results from REST requests // to JavaScript formats the GUI expects. dublintech.dataAdapter = { adaptStudents : function (data) { var adaptedStudentsVar = { students:[] }; jQuery.each(data.students, function(indx, originalStudent){ var student = { name: originalStudent.firstName + " " + originalStudent.lastName, dateOfBirth: originalStudent.dateOfBirth, nationality: originalStudent.nationality }; adaptedStudentsVar.students.push(student); }); return adaptedStudentsVar; }, adaptHumans : function (data) { // ... // code to adapt humans }, adaptAnimals : function(data) { // ... // code to adapt animals. } };This approach achieves a separation of concerns and is a good attempt at making things follow a stateless and functional paradigm.
Note 1: Yes the above example is super simple. The only adaptation that is really happening is that the adpated name variable is made up from combining the first name with the last name that are in the JSON. The real world is obviously a more complicated place, but this simple adaptation example is enough to show how things hang together using QUnit.
Note 2: If you are wondering why I did not use a closure above, it is because there is no need for any state in these methods, hence there is no need to encapsulate any state. But again, in the real world you may not find it so easy to avoid state and if it comes you are better off encapsulating it using a closure.
And now the tests...
Ideally you'd like if:- any required testing libaries were taken from a public CDN.
- your tests are 100% separate from your JavaScript code and have no impact your original source code.
- your tests are easy to run and even easier to get results from.
<html> <head>QUnit basic example </head> <body><!-- test code