multiple CPPUNIT_TEST() not work as expected

Help
2006-11-13
2013-04-22
  • Ben Kuehmichel
    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