Wednesday, November 21, 2012

The Technology Radar

Acclaimed IT Consultancy company ThoughtWorks recently published its October Technology Radar.
This publication assessess software techniques, software tools, software platforms, software languages and makes recommendations regarding the various offerings.

In a world where the technologies changes are rapid and where choices can seem overwhelming it is a super publication and well worth reading. It is not everyday when industry Gurus such as Martin Fowler (Chief Scientist at thoughtworks) are going to tell you their expert opinions for free.  Some of the interesting points from the latest technology radar:
  1. The proliferation of work - in - progress limits. One method to achieve this is to use Kanban limits. "Kanban" traces back to the early days of the Toyota Production system and in English it is roughtly translated to "signboard". One aspect of the Kanban system is to limit impedemence mistmatch between inter-dependent processes by imposing work-in-process limits. So there is not point having a massive amount of development in progress at any one time and then all a sudden dumping this on a test teaam.
  2. 'Mobile first' - this is a technique which considers the mobile devices rather than last.  Some simple stats substantiate this:
  3. Regarding the build tools, Maven is going out of fashion. Interestingly because it never fully dumped XML.  I tend to agree with this.  While Maven offered some improvements over Ant in how it handled Maven, if you wanted to do anything which was not the Maven way you had to write a plugin which some people found hacky especially as project complexity grows.  Rake and Gradle offer better alternatives.
  4. The testing framework Jasmine for JavaScript gets a lot of praise.  QUnit (the one from JQuery which this blog covered recently) doesn't get any. Jasmine is more geared towards BDD whereas QUnit is more TDD.
  5. Very interestingly the performance and scalability tool Locust is suggested over JMeter. One advantage Locust has is that it is not thread bound. This means you do not need a separate thread to simulate every client.  to simulate some geographical dispersion amongst your clients  Saas Performance testing tools such as Blitz.io and Tealeaf are suggested as tools on the up.
  6. The most popular project in GitHub (over 40,000 stargazers at time of writing), Twitter Bootstrap is promoted for its powerfuls of components and features. I really like the look of Twitter Bootstrap. It is used by NASA, MSNBC and practically every start up.

Wednesday, November 14, 2012

Unit Testing your JavaScript

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:
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.
To use the QUnit approach we simply write some JavaScript using the QUnit APIs in a HTML page. See below:
<html>
<head>
  QUnit basic example
  
  
  
  
</head>
<body>
  
<!-- test code </body> </html>

Now the salients points:
  1. The test exists in a separate file. It creates some test data, passes it to the adaptStudents method and checks that what is returned is what it should be.
  2. The JavaScript which contains the code that is being tested can be located anywhere that can be accessed by a HTTP request. So your test code does not have be located on the same machine / building as the JavaScript it is testing.
  3. The QUnit, JQuery libraries are pulled in from a CDN. 
  4. The test() API is a QUnit API which does exactly what it says  - that there is a test to execute!  There can be multiple tests() in the same file and they can be grouped using the module() API.
  5. equal() is a QUnit API which performs the actual test. QUnit has other assertion APIs (ok() and deepEqual()).
  6. It's simple to run this test. Just access this page in a web browser.
When the test is run, you get a picture like this:
Results
The results contain the following checkboxes
  • Hide passed tests - useful when you want to focus only on tests that failed
  • Check for globals - when selected QUnit will make a list of all properties on the window object, before and after each test and will check for differences. If properties are added or removed, the test will fail. 
  • No try/catch - If your test throws an exception, the testrunner will die, unable to continue running and will you will get the a  "native" exception. This can help debugging old browsers with bad debugging support like Internet Explorer 6.
The results page also contain the user agent used to run the tests (useful for screen shots), the total number of tests ran, the success summary and the overall execution time.  Each test is then detailed - including the number of failures, the numbers of success and the number of asserts in the test i.e. in this case (0, 3, 3).  You can also specify the number of assertions in a test and if they are not all invoked, the test will fail.

Anything else? 

Yes, QUnit can be used to test Asychronous code.  There are special APIs to indicate asynchronous code is being tested. QUnit can also test user interaction by leveraging JQuery trigger APIs.

What about mock objects?

There is no support for mock objects out of the box. However, there are a number of frameworks such as mockjax and sinjo.js  (in fact sinon.js has special support for QUnit).
Finally, I have put the source code detailed above on my Github.