[Cppunit-devel] CppUnit, one instance of a fixture per test run
Brought to you by:
blep
From: Eddie P. <ed...@re...> - 2005-05-10 20:24:01
|
Hello! We ran into a little difficulty with CppUnit here, and so I've built a solution for it, and I'm wondering if it would be of use to the CppUnit world at large. What we found, was that CppUnit ends up creating a new instance of a fixture for each test method it's about to run. We were relying on the fact that CppUnit would have one instance of a fixture, and iterate through each of the methods enclosed, so that we could do some expensive construction only once, and not have it happen for every test. Anyhow, after rooting through the HelperMacros.h file (thanks for documenting it! :-)), I found the root of our problem was the CPPUNIT_TEST macro: /*! \brief Add a method to the suite. * \param testMethod Name of the method of the test case to add to the * suite. The signature of the method must be of * type: void testMethod(); * \see CPPUNIT_TEST_SUITE. */ #define CPPUNIT_TEST( testMethod ) \ CPPUNIT_TEST_SUITE_ADD_TEST( \ ( new CPPUNIT_NS::TestCaller<TestFixtureType>( \ context.getTestNameFor( #testMethod), \ &TestFixtureType::testMethod, \ context.makeFixture() ) ) ) Apparently the problem is the context.makeFixture() call will create a new fixture per method, which destroys our ability to construct things only once. As such, what I've done is the following: 1) Move the bulk of the 'logic' from CPPUNIT_TEST to a macro I call CPPUNIT_COMMON_TEST, and wired CPPUNIT_TEST to use it: /*! \brief The common meat of adding a test * * This is used internatlly by CPPUNIT_TEST_AS_PART_OF_ONE_FIXTURE * and CPPUNIT_TEST * * \param testMethod Name of the method of the test case to add to the * suite. The signature of the method must be of * type: void testMethod(); * * \param fixture The fixture instance to execute against. * \see CPPUNIT_TEST CPPUNIT_TEST_AS_PART_OF_ONE_FIXTURE */ #define CPPUNIT_COMMON_TEST( testMethod, fixture ) \ CPPUNIT_TEST_SUITE_ADD_TEST( \ ( new CPPUNIT_NS::TestCaller<TestFixtureType>( context.getTestNameFor( #testMethod) \ , &TestFixtureType::testMethod \ , fixture \ ) ) ) /*! \brief Add a method to the suite. * \param testMethod Name of the method of the test case to add to the * suite. The signature of the method must be of * type: void testMethod(); * \see CPPUNIT_TEST_SUITE. */ #define CPPUNIT_TEST( testMethod ) \ CPPUNIT_COMMON_TEST( testMethod, context.makeFixture() ) 2) Created a variant of CPPUNIT_TEST that uses a variable fixture from another macro I'll define in step 3: /*! \brief Executes a test against the fixture specified earlier * * This will add a test, however it will use the fixture specified * in CPPUNIT_ONE_TEST_FIXTURE_ONLY. * Make sure to call CPPUNIT_ONE_TEST_FIXTURE_ONLY before this. * * \param testMethod Name of the method of the test case to add to the * suite. The signature of the method must be of * type: void testMethod(); * \see CPPUNIT_ONE_TEST_FIXTURE_ONLY */ #define CPPUNIT_TEST_AS_PART_OF_ONE_FIXTURE( testMethod ) \ CPPUNIT_COMMON_TEST( testMethod, *pTestFixture ) 3) Created a new macro, to be used after CPPUNIT_TEST_SUITE, if you want this functionality: /*! \brief Creates only one fixture for the run * * This macro is to be used after CPP_UNIT_TEST_SUITE. * It will build one test fixture, to be used for each of the * test runs. */ #define CPPUNIT_ONE_TEST_FIXTURE_ONLY( ) \ TestFixtureType *pTestFixture = context.makeFixture() So, the usage will be something like this: class StringTests : public CPPUNIT_NS::TestFixture { public: StringTests(); ~StringTests(); private: CPPUNIT_TEST_SUITE ( StringTests ); CPPUNIT_ONE_TEST_FIXTURE_ONLY(); CPPUNIT_TEST_AS_PART_OF_ONE_FIXTURE( TestFoo ); CPPUNIT_TEST_SUITE_END(); void TestFoo (); }; Anyhow, I'm looking for some feedback: I'm not super happy with the macro names, but they seem explicit enough. Would this be welcomed as a patch to HelperMacros.h, or some variant thereof? I look forward to your response! Cheers, -e- |