Ben Kuehmichel - 2006-11-13

I was writing some tests on a piece of code that uses quite a bit of memory and ran into memory issues on my machine.  Under normal dev and debug situations I have no problem with this so I started to look at what what going on and came up with this simple test that gave quite unexpected results (at least unexpected to me).  I modified the code from the simple_plugin example to create this case.

// ExampleTestCase.h
#ifndef CPP_UNIT_EXAMPLETESTCASE_H
#define CPP_UNIT_EXAMPLETESTCASE_H
#include <cppunit/extensions/HelperMacros.h>
class ExampleTestCase : public CPPUNIT_NS::TestFixture
{
  CPPUNIT_TEST_SUITE( ExampleTestCase );
  CPPUNIT_TEST( example );
  CPPUNIT_TEST( anotherExample );
  CPPUNIT_TEST( testAdd );
  CPPUNIT_TEST( testEquals );
  CPPUNIT_TEST_SUITE_END();

protected:
  double m_value1;
  double m_value2;
  static int count;
  int counter;

public:
   ExampleTestCase();
  void setUp();

protected:
  void example();
  void anotherExample();
  void testAdd();
  void testEquals();
};
#endif

// ExampleTestCase.cpp
#include <cppunit/config/SourcePrefix.h>
#include "ExampleTestCase.h"
#include <qstring.h>

CPPUNIT_TEST_SUITE_REGISTRATION( ExampleTestCase );

int ExampleTestCase::count = 0;

ExampleTestCase::ExampleTestCase()
:counter(count++)
{
   qDebug("counter="+QString::number(counter));
   qDebug("ExampleTestCase::ExampleTestCase()");
}

void ExampleTestCase::example()
{
   qDebug("counter="+QString::number(counter));
   qDebug("ExampleTestCase::example()");
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, 1.1, 0.05 );
  CPPUNIT_ASSERT( 1 == 0 );
  CPPUNIT_ASSERT( 1 == 1 );
}

void ExampleTestCase::anotherExample()
{
   qDebug("counter="+QString::number(counter));
   qDebug("ExampleTestCase::anotherExample()");
  CPPUNIT_ASSERT (1 == 2);
}

void ExampleTestCase::setUp()
{
   qDebug("counter="+QString::number(counter));
   qDebug("ExampleTestCase::setUp()");
  m_value1 = 2.0;
  m_value2 = 3.0;
}

void ExampleTestCase::testAdd()
{
   qDebug("counter="+QString::number(counter));
   qDebug("ExampleTestCase::testAdd()");
  double result = m_value1 + m_value2;
  CPPUNIT_ASSERT( result == 6.0 );
}

void ExampleTestCase::testEquals()
{
   qDebug("counter="+QString::number(counter));
   qDebug("ExampleTestCase::testEquals()");
  long* l1 = new long(12);
  long* l2 = new long(12);

  CPPUNIT_ASSERT_EQUAL( 12, 12 );
  CPPUNIT_ASSERT_EQUAL( 12L, 12L );
  CPPUNIT_ASSERT_EQUAL( *l1, *l2 );

  delete l1;
  delete l2;

  CPPUNIT_ASSERT( 12L == 12L );
  CPPUNIT_ASSERT_EQUAL( 12, 13 );
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 12.0, 11.99, 0.5 );
}

I expected this to show the constructor get called once and then for each CPPUNIT_TEST() to see setUp() called.  Instead, I get this:
D:\test>DllPlugInTesterd_dll.exe D:\DQ_XI\11.6_Dev\ui_testing\cppunit\Debug\pa_unitd.dll
counter=0
ExampleTestCase::ExampleTestCase()
counter=1
ExampleTestCase::ExampleTestCase()
counter=2
ExampleTestCase::ExampleTestCase()
counter=3
ExampleTestCase::ExampleTestCase()
.counter=0
ExampleTestCase::setUp()
counter=0
ExampleTestCase::example()
F.counter=1
ExampleTestCase::setUp()
counter=1
ExampleTestCase::anotherExample()
F.counter=2
ExampleTestCase::setUp()
counter=2
ExampleTestCase::testAdd()
F.counter=3
ExampleTestCase::setUp()
counter=3
ExampleTestCase::testEquals()
F

Why is the test class getting instantiated for each CPPUNIT_TEST() call?  This is killing my tests on memory usage to have as many instances of my class alive as I have separate test cases.  What point are setUp() and tearDown() if we are instantiating a new class instance each time?  The constructor and destructor are good enough then!  I would expect CPPUNIT_TEST_SUITE( ExampleTestCase ); to create a class instance, each call to CPPUNIT_TEST(testCase) to call setUp(), my test method and tearDown() and then for CPPUNIT_TEST_SUITE_END(); to destroy that one instance.  Is this a bug?  Or am I missing something about how I am supposed to use this?

Thanks,
Ben