Thursday, May 25, 2006

A difficult simple test framework

I'm working on writing a few unit tests for the latest of my projects and have come up with a fairly simple test code template that allows both easy implementation as well as straightforward extensibility.

The general idea is to put all the test cases into an array of function pointers. The following is an example of the code:

// Define the shape of the function pointer
typedef void(*fn_ptr)(DataType&);
#define TESTCASE(fn) void (fn)(DataType& param)

TESTCASE(test1); // Declare a testcase
TESTCASE(test2); // Declare another

// Define the global array
const fn_ptr test_array[] =
{
   test1,
   test2,
};
const int NumOfCases = sizeof(test_array) / sizeof(fn_ptr);

// implement the test case
TESTCASE(test1)
{
   // Do something
}

// The main test driver
int main()
{
   ...
   for (int i=0; i<
NumOfCases; i++)
   {
      // do some test case initialization
      (*test_array[i])(param);
      // clean up the test case resources
   }
   ...
}

The benefit of this code is that once the test case initialization and cleanup are taken care of, the developer/tester can concentrate on implementing test cases rather than trying to worry about those mundanities in every test case. The test case writer just comes up with a good name for a test case, uses the TESTCASE() macro to declare the function, adds the new function to test_array[], and then adds the test implementation. The test will automatically be run the next time through, plus there is no reason why tests can't be injected directly into the array rather than appended to the end. One other benefit that is realizable with this setup is that with good planning, it may be possible to break the array into discrete test areas such that only the test cases specified by offset are run (I may add this functionality later if it is useful and necessary).

The drawback is (besides its unreadability) is that it is tedious to add a function declaration AND add that new function to test_array[]. What I am trying to think of here is a way to condense those two operations into a single operation which would simplify this test program template even further. It does no one any good if a test case is written but is never entered into the test_array.

Visual Studio 2003 has macro capabilities, and I may end up relying on that, but I'd much rather be able to implement something using the standard C++ preprocessor and compiler stack rather than anything IDE-specific. As of now, I'm doing it by hand and it is error prone and difficult once the list of test cases becomes longer than half the screen size.

If there is a better way to do this, I'm all ears.

0 Comments:

Post a Comment

<< Home