Possible bugs in Registry extension files?

  • I think these are bugs, but as I'm just getting used to the CppUnit framework I'm not sure:

    (1) In TestFactoryRegistry::makeTest(), I think that the line
      TestSuite *suite = new TestSuite( "All Tests" );
    should really be
      TestSuite *suite = new TestSuite( m_name );
    Otherwise, the suite generated will not have the correct name.

    (2) In AutoRegisterSuite(const std::string&), I think that the line
      TestSuiteFactory *factory = new TestSuiteFactory<TestCaseType>();
    should really be
      TestFactory *factory = new TestSuiteFactory<TestCaseType>();
    Otherwise, it doesn't match the defautl ctor (and, in fact, won't compile).

    (3) I'd suggest adding a macro to autoregister a suite by name, such as
       #define CU_TEST_SUITE_NAMED_REGISTRATION( ATestCaseType, SuiteName )
         static CppUnit::AutoRegisterSuite< ATestCaseType >
           CU_MAKE_UNIQUE_NAME(__autoRegisterSuite )(SuiteName)

    These changes were motivated by me trying figure out how the factory and registry extension classes worked -- I decided to try and modify the HostApp demo somewhat so as to contain two testcases, each in it's own separate suite.  That is, in HostAppDoc.cpp I changed
      runner.addTest ( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
      runner.addTest ( CppUnit::TestFactoryRegistry::getRegistry("Suite1").makeTest() );
      runner.addTest ( CppUnit::TestFactoryRegistry::getRegistry("Suite2").makeTest() );

    This makes for a nicer example, I think.

    Also, does anyone know how to get the HostApp demo to invoke the test runner GUI as a standalone app, i.e. without requiring the underlying "empty" app shell to appear?


    • Just to make thing clear from the start: when I wrote the test registry, I planned the named suite feature, but it has not been tested yet (because of the ownership issue discussed in TestFactoryRegistry.cpp). So you're ahead of me from that point.

      (1) yes it is a bug.
      (2) it has been corrected in the current CVS.
      (3) It is indeed the macro to go along with the named constructor. Though it won't be commited until the ownership issue is fixed.

      To run the test without the doc/view stuff, look at the file in the CVS browser: cppunit\examples\msvc\CppUnitTestApp\CppUnitTestApp.cpp. There is a RunTests() method in the App which run the test. The code that showed the dialog afterward has been removed.

      Thanks a lot for your feeback. If you can subcribe to the dev-list to discuss features. I could really use more feedback from Windows user.


      • Well, it turns out I can't make use of the registry functionality anyway: near as I can tell, global ctor's in libraries aren't exported to the calling context under MSVC6.  That is,

        - suite1.lib contains a bunch of testscases, all auotregister'd into "Suite1"

        - main driver contains the line
           masterSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry("Suite1").makeTest() );

        At runtime, the registry lookup doesn't find "Suite1", because the ctor wasn't linked in to the executable -- because there's no reference to it from main.

        [Editorial: I suspect MSVC6 is broken here, because it only fails to work when Suite1 is in a separate library.  Global ctors should always be respected, no?]

        This is a pain, because I've got a lot of testcases and a lot of libraries and a lot of developers to deal with -- it would have been nice to have it all just magically work, without a lot of explicit includes and suite creation calls.  So much for the magic of registries and factories; back to the drawing board...

        I'll migrate over to the dev-list.


        • It can be done.
          The response is on the dev-list ;-)
          seek "TestFactoryRegistry and Library"


    • Mark Delaney
      Mark Delaney

      I am having great trouble doing this. (using 1.6.2) I have a static .LIB. In it I have a scaffolding.cpp file for the code to connect the .LIB to my EXE. It has

      #include "stdafx.h"
      #include "scaffolding.h"
      #include "cppunit\TestSuite.h"
      #include "cppunit\extensions\TestFactoryRegistry.h"
      using namespace CppUnit;

      Test *getLibrarySuite()
         TestSuite *suite = new CppUnit::TestSuite( "MyProject Unit Tests" );
         TestFactoryRegistry::getRegistry().addTestToSuite( suite );
         return suite;

      The scaffolding.h file has

      #include "cppunit\test.h"
      CppUnit::Test *getLibrarySuite();

      In my EXE, I call this function

         void CQVPakApp::RunTests()
           TestRunner runner;
           runner.addTest ( getLibrarySuite() );

      It appears that I am doing exactly what I should, but I am having the problem with static libs that is discussed several times in the message traffic here and on dev-list over the last few months. Is there something I am missing? Is the suggested fix for a version other than 1.6.2?

      Thank you for your assistance.

    • Mark Delaney
      Mark Delaney

      After much thrashing, I have the following solution. On MSVC 6.0 (SP3), on Windows 2000, running CppUnit 1.6.2, I can avoid the dreaded linkage defect by putting all of the test suite registrations into the .CPP file that implements the exported function for getting the registry's tests. If I put the CPPUNIT_TEST_SUITE_REGISTRATION macros in the same file as getMyTest() everything is fine. If I put them in the individual .CPP files that implement each test suite nothing shows up. I get an empty suite.


      CppUnit::Test* getMyTest()
         return TestFactoryRegistry::getRegistry().makeTest();

      1) I hope this helps the rest of the MSVC world avoid spinning their wheels. I am looking forward to getting some value from the tool.

      2) I would be happy to have an authorative explanation of why this works, to further my education regarding all things linker-ish.

      3) I had to adapt the GUI (only) to Unicode. Does the core development group here want to see how I did it? Or is this work that you don't care about, or have already done?