Thursday, March 10, 2005

Test Driven Development

I’ve spent the last few days evaluating various automated testing tools. I’ve looked at Test Complete, FitNesse, and NUnit.

The one I’ve spent the most time with so far is TestComplete. This is an all-in-one testing tool that provides for unit testing, integration testing, acceptance testing, and load testing. It allows you to write script code that runs within the TestComplete user interface. It also allows you to record your activity (screens, mouse moves and clicks) so that you can repeat a series of events. The scripting tool seemed powerful enough to do most tasks, and it allows you to write your script in several different languages (C# script, Delphi, VB Script, Javascript).

It also includes hooks into various development tools. In my testing, I was able to tell TestComplete to run a C#.Net test harness application that I wrote. The test harness then made calls to some production code I had written that does various business rule processing tasks. When I ran the test, TestComplete fired up my test harness application, made the method calls are reported on their failure (if an exception was throw) or success. The integration also went the other way, allowing me to write code in my test harness application that interacted with TestComplete (for instance, writing some values to the test log).

I found TestComplete to be somewhat difficult to learn and not very intuitive. It is a very powerful tool that can do it all. Once I started to get the hang of it, I was able to fairly quickly develop some robust tests, but it took several hours before I got there.

The unit testing tool that I find most compelling is FitNesse. FitNesse is a Wiki-based tool that allows you to easily create unit tests, and aggregate those into test suites.

I wanted to test a little math application, so I created a test harness that called the Add method. The only requirement is that I reference the fit.dll library and that my test harness class extend fit.ColumnFixture.

Once I compiled my test harness, I could easily create a Wiki page to test it. I specify where to find the test harness .dll file, and I specify testing data and the expected results. The test is defined by building a table, similar to this:

!path C:\root\Math\MathClass.dll
!MathClass.MathTest
a b TestAdd?
1 1 2
10 10 20
100 100 500

As you can see, the !path command tells FitNesse where to find my code. The table itself is built with values separated by bars. The first line specifies the namespace and class. The second line specifies the values to test and the method to call. In my code, I had to public integer fields (a and b), and a method called TestAdd. TestAdd calls my Add method in my production code, passing a and b.

The first test sets a to 1, sets b to 1, and calls the method. We’ve specified that we expect a 2. The second test passes 10 and 10 and expects 20. The third test passes 100 and 100 and expects 500 (this one should fail).

When we view the test page in the Wiki, it looks like this:
MathClass.MathTest
abTestAdd?
112
101020
100100500

When we click the “Test” button, we get this:
MathClass.MathTest
abTestAdd?
112
101020
100100500 expected

200 actual

Seeing the test results in this table makes it very easy to see the results. As long as the developer is disciplined enough to build a test table for each piece of code and tests it regularly, I can see where FitNesse would be a valuable unit testing tool.

No comments: