Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: debugging question (long post) regression testing

Author: Michel Langeveld

Date: 12:18:28 06/29/03

Go up one level in this thread


Here is my 2 cents about regression testing

With this approach you can find differences among 2 seperate runs
of the same program.

I found already quiet a number of bugs with it and I could explain odd behaviour
which else would cost me weeks.

The first time you can run a program like here:

//
//Debug Test program by Michel Langeveld
//wrote it here in CCC from scratch so hope it compiles
//
#include <stdio.h>
#include "debugchecker.h"

int main()
{
   DebugChecker debug("debug.txt");
   char tmp[100];

   for (int i=0; i<1000; i++)
   {
      sprintf(tmp, "%d", i*i);
      debug.doit(tmp);
   }

   return 0;
}

During the 1st run it creates a file called debug.txt and it writes on all calls
of doit on smart places results to it.

The 2nd time you can run it ... instead of in write modus the debug object
switches to checking modus (reading modus)....

It checks the following:
- if all results are EXACTLY the same
- if the previous run did not generate less or more lines like before

Put this in all your interresting functions ... for example everywhere where you
do nodeCounter++... and you are able to compare runs of your program

Sometimes I work with logfiles of 400Mb... or even larger
If it finds a difference you can run your program again on the exact same
data in debugmodus.

It's even possible to compare:
- the current program vs and previous version of your program
- debugmode vs release mode of your program.
- whole different machine/compiler/operating system

You can change your movegenerator, put your evaluation function upside down....
after running WAC, ECM, or so you can see still if it produces exactly the same
result.


Have fun!

----------------- begin debugchecker.h ----------------------

//
//DebugChecker object for regression testing
//Wrote by Michel Langeveld
//
#ifndef DEBUGCHECKER_H
#define DEBUGCHECKER_H

#include <stdio.h>

class DebugChecker
{
public:

   DebugChecker( char* filename );

   ~DebugChecker();

   void doit(char *str);

private:
   typedef enum modusType { eReadModus, eWriteModus, eErrorModus };

   FILE *debugFile;
   char debugFileName[1000];

   modusType modus;

   long lines;
};

#endif

----------------- end Debugchecker.h ----------------------

----------------- Begin debugchecker.cpp ----------------------

#include <string.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

#include "debugchecker.h"
#include "utility.h"

using namespace std;

//
// Constructor
//
// Try to open a file for reading or writing
DebugChecker::DebugChecker( char* filename )
{
   lines = 0;

   modus = eErrorModus;

   //try to open a file for reading
	this->debugFile = fopen(filename, "rb");
	if (this->debugFile != NULL)
   {
      //set the new name
      strcpy(this->debugFileName, filename);

      modus = eReadModus;
   }

   //try to open a file for writing
   if (modus == eErrorModus)
   {
   	this->debugFile = fopen(filename, "wb");
   	if (this->debugFile == NULL)
      {
   		cerr << "Error: During creating debugfile '" << filename << "'" << endl;
         exit(1);
      }
      else
      {
         modus = eWriteModus;

         //set the new name
         strcpy(this->debugFileName, filename);
      }
   }

}

//Close the file and look if no more lines available
DebugChecker::~DebugChecker()
{
   if (modus == eReadModus)
   {
      char buffer[10000];
      if (fgets(buffer, 10000, this->debugFile) != NULL)
      {
         cerr << "Error: During closing debugfile: '" << this->debugFileName <<
"' at line:" << lines << endl;
         cerr << "There is still data left: '" << buffer << "'." << endl;
      }
   }

   if (this->debugFile)
   {
      int stat = fclose(this->debugFile);
      if (stat != 0)
      {
         cerr << "Error: During closing debugfile: '" << this->debugFileName <<
"' at line:" << lines << endl;
         exit(1);
      }
   }
}

void DebugChecker::doit(char *str)
{
   lines++;

   if (modus == eReadModus)
   {
      char buffer[10000];

      if (fgets(buffer, 10000, this->debugFile) == NULL)
      {
         modus = eErrorModus;
         cerr << "Error: During reading from debugfile: '" << debugFileName <<
"' at line:" << lines << endl;
         cerr << "Missing expected data: '" << str << "]." << endl;
         exit(1);
      }

      rtrim(buffer, '\n');
      rtrim(buffer, '\r');

      if (strcmp(buffer, str) != 0)
      {
         modus = eErrorModus;
         cerr << "Error: During reading from debugfile: '" << debugFileName <<
"' at line:" << lines << endl;
         cerr << "Expected : '" << str << "'" << endl;
         cerr << "Found    : '" << buffer << "'" << endl;
         exit(1);
      }

   }
   else if (modus == eWriteModus)
   {
      if (fprintf(this->debugFile, "%s\n", str) == 0)
      {
         modus = eErrorModus;
         cerr << "Error: During writing to debugfile: '" << this->debugFileName
<< "' at line:" << lines << endl;
         cerr << "Could not write the string: " << str << endl;
         exit(1);
      }
   }
}

----------------- end debugchecker.cpp ----------------------




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.