Testing Class Templates

In the software biz it is common to spend as much time/effort in testing as in creating - the two go together inextricably. Often the builders don't fully understand the product nuances until they start creating the testing environment. 

When making something like a container or other class templates, it is standard practice to have test harnesses that can be reconfigured with small edit changes. Here is a way to set one up for Stack:

// choose one from group A

//  A1: makes stacks of char
typedef char ElementType;
ElementType fill = '*';
const size_t maxSize = 15;
const char* eT = "char";
const char ofc = '\0';
const int  dir = +1;
// end A1 */

/* //  A2: makes stacks of String
#include <xstring.cpp>
typedef fsu::String ElementType;
ElementType fill = "*";
const size_t maxSize = 100;
const char* eT = "String";
const char ofc = ' ';
const int  dir = +1;
// end A2 */

/* //  A3: makes stacks of int
typedef int ElementType;
ElementType fill = 0;
const size_t maxSize = 100;
const char* eT = "int";
const char ofc = ' ';
const int  dir = +1;
// end A3 */

/* //  A4: makes stacks of Product objects
#include <product.h>
#include <product.cpp>
#include <cstringdiff.h>
#include <cstringdiff.cpp>
typedef Product ElementType;
ElementType fill = Product();
const size_t maxSize = 100;
const char* eT = "ID";
const char ofc = '\n';
const int  dir = -1;
// end A4 */

/* //  A5: makes stacks of ID objects
#include <id.h>
#include <id.cpp>
#include <cstringdiff.h>
#include <cstringdiff.cpp>
typedef ID ElementType;
ElementType fill = ID();
const size_t maxSize = 100;
const char* eT = "ID";
const char ofc = '\n';
const int  dir = -1;
// end A5 */

#include <stack.h>
typedef fsu::Stack < ElementType , maxSize > StackType;

To change from one type to another just insert "/*" in one place and remove it from another. Then you write the test using ElementType and StackType, as in:

int main( int argc, char* argv[] )
{
  bool BATCH = 0;
  if (argc > 1)
  {
    if (argv[1][0] != '0') // user entered 0 
      BATCH = 1;
  }
  std::cout << "This is a Stack < " << eT << " > test program\n";
  DisplayMenu();
  StackType s(fill,ofc,dir);
  ElementType Tval;
  char option;
  do
  {
    std::cout << "Enter [command][argument] ('M' for menu, 'Q' to quit): ";
    std::cin >> option;
...

Other points about testing templates:

  1. A function template will not be compiled unless it is actually called by a client program. 
  2. Since member functions of a class template are function templates, these will also not be compiled unless called in a client program.

The net effect of 1,2 is that you have to actually exercise a member function to have it compile. This holds for all member functions, including operators, constructors, the copy constructor. (Be sure to test copy and assignment. See LIB/tests/fbitvect.cpp for a way to do this.)