Friday, June 09, 2006

Sharing initialization across Unit Tests

In principle unit tests should be isolated from each other to ensure that running one unit test does not influence another. There is however, I believe, a case where having a shared initialization between unit tests can make a lot of sense. Whenever a time consuming initialization needs to take place, and when one can ensure that the state of the initialized environment does not influence in any way the tests, then it is really important to share initialization. One of the goals of unit testing is to make it easy to test, to promote a test-often approach and that will conflict with long initialization times. An initialization that takes a couple of seconds, although very acceptable for a running application is not acceptable at all for unit testing. If you do follow the test-often approach, you will be building a large number of tests (not hard to admit you will have several dozens, hundreds of tests). Multiply that by the initialization cost and testing becomes unbearable.

Example of the above. I have been working for sometime with WebWork+Spring+Hibernate and using JUnit for unit testing integrated in the build/deployment process via Ant. The startup time for the system is around 8 seconds (still way lower than a full J2EE application server startup time ;-)...but after even a mere 12 tests it becomes impossible to have to wait for a simple test run. By isolating the initialization of WebWork+Spring+Hibernate in a shared initialization class, I was able to reduce the overall tests run time by a huge factor. Somewhere from 104s to 12s in my simple (very simple) case of 12 tests.

The solution for me, I create a singleton class that isolates all shared initialization then I make sure all tests run via ant using the task batchtest with forking enabled and with forkmode set to 'perBatch' (see http://ant.apache.org/manual/OptionalTasks/junit.html) and voila, I get shared initialization and a huge reduction in test running.

After looking online for similar issues, I found the link http://beust.com/weblog/archives/000082.html that talks a bit about this same issue confirming my worries and validating this approach.

My belief in unit testing restored, I continue my development with my nice safety net in place...

Wednesday, June 07, 2006

FireBug

Every developer "carries" his bag of tools around when doing their work...This bag of tools can represent a precious advantage since a good tool applied at the right moment can bring speed and quality to the development effort. It is quite unlikely you will find a tool that "fits all" (a tool for each job) and the developer does need to know enough of the tool and problem to solve to make it useful (it is not the weapon that makes the warrior, it is the warrior that makes the weapon). But sure enough, some tools are just too good and should be in every developer's bag. A tool which I found to be a must for any serious web developer doing from just regular HTML coding to AJAX development is the Firebug Firefox extension (you are using Firefox right?!?! ;-) ). The tool allows you (among other functionality) to:

  • Inspect HTML, by moving your mouse around you can get to see the HTML snippet relevant to the element highlighted on the browser.
  • Inspect properties like positioning, styles on inspected HTML elements.
  • Inspect events happening in your pages.
  • Inspect the DOM of your page.
  • Perform Javascript debugging.
  • Show all AJAX interactions between your page and the underlying server.
  • Show all kinds of errors (e.g. CSS, Javascript, etc)
In short, if you are doing web development and have not seen Firebug in action before, you should spend sometime looking at it...It will save you hours in any future development. It sure is in my bag of tools to stay. :-)