Unit Testing

Most developers agree that testing is important but few test their code. Even fever do it methodically. Many developers do not realize that there is a difference between "my code is working" and "my code is correct". My code is working means that I clicked around and I am getting the functionality I desire. My code is correct means that I have verified that my code will always do what I expect it to do. For example,

// $a = 1, $b = '1'
print $a + $b;

In this one line PHP code, the develop wishes to add two integers. What he doesn't realize is that $b is a string. The line outputs the correct result but the developer is unaware of the implicit casting. Under rare cases, $a would also be cast to string or perhaps it was a string which usually casted to int but in this particular case, it did not cast to int. The result is that this one line code is now adding two strings. The output is:

Parse error: syntax error, unexpected T_LNUMBER in x.php on line 2

If the developer had verified that the code is correct, this problem would not occur. Such problems are very common in PHP code today. Unit testing can help eliminate most of these errors and unit test can be used to verify that the code is correct.

Most developers test and debug by either clicking around or inserting debug statements to find the problem. These are desperate measures taken by someone who doesn't know better or is unable to debug in an orderly fashion due to architectural constraints. Debugging in orderly fashion means unit testing. The architecture of a software can make it difficult to unit test. For example, it is difficult to unit test Moodle, Drupal and Elgg without editing the core. So all three have added support for unit testing in their core, making unit testing very easy and now developers to not have to edit the core to unit test.

Why unit test
The goal of unit testing is to isolate pieces of a program/application/software and then show that each piece is functioning correctly. Unit tests find problems early in the development cycle thus reducing errors and debugging time later on. Unit tests allow programmers to retest their code in future and make regression testing easier. Since unit tests include test cases, they serve as a form of documentation. It is important to note that unit test do NOT replace higher level functional or system testing.

There are two important concepts in unit testing.
1. Think about what can go wrong with the code and write code to test for it
2. Test at granular levels and fix problems early so that you have fewer problems later
A unit is the smallest testable piece of source code. A unit could be an object, function, or even a loop. For example, a unit test could be used to test whether a loop terminates prematurely or whether a function which is supposed to return a string is returning an integer. Unit tests are generally run every time a code has been changed anywhere. This way if a change inadvertently changed something else in the code, it would be reported right away and the developer would be able to fix it immediately rather than having to do painstaking debugging later when the inadvertent change becomes a visible bug.

The primary arguments against unit testing is that it takes too long (so much more code to write especially for newbies), relatively steep conceptual learning curve, assumption that nothing could go wrong with this piece of code, and most of us find testing to be boring and waste of our valuable time.

My experience with unit testing is that it helps me write better code and make it easier to find and fix errors. Testing is boring but not frustrating.

Programming languages supporting unit testing
Java and Python 2.1 and above come with a unit testing framework. Java provides JUnit and Python provides unittest. Most languages do not come with pre-package unit testing frameworks but free open source unit testing frameworks are readily available online for all major languages. For example, SimpleTest and PHPUnit are available for PHP. In addition, several open source software such as Drupal, Moodle, and Elgg integrate unit testing frameworks in their core to enable fast, easy, and efficient unit testing.