Since you're sane and understand AlternateHardAndSoftLayers as well as RefactoringWithCeePlusPlus, you may start thinking about how you'd unit test C++. The various incarnations of CppUnit are horribly bloated; you can go far farther with a lot less. Here's the deal: * A TestFixture is a class that resides in the same compilation unit as the class it tests. The only thing important about it is its name begins with an underscore where your product classes don't. So ''struct Foo'' is tested by something named ''struct _Foo''. * No ''setup'' and ''teardown'' methods - those are just _Foo's ctor and dtor. Leave 'em blank to start - you only use 'em when the TestCase''''''s have some commonality you want to make OnceAndOnlyOnce. * Each TestCase is just an inline method of the TestFixture class. To make things simple, give them all the same signature; for example ''struct _Foo { void testBar(TestVisitor & v) { ... } };'' * template functions make it easy to run these. Since novices have a hard time with templates, I'll paste in a snippet that works okay: template < class TestFixture > void runTest ( TestVisitor & testVisitor, char const * const testName, void (TestFixture::* testCase )(TestVisitor &) ) { try { TestFixture f; (f.*testCase)(testVisitor); testVisitor.describe(testName); // streams the good/bad notification } catch(exception e) { testVisitor() << "EXCEPTION: " << e.what() << " in " << testName << endl; } catch(...) { testVisitor() << "EXCEPTION: unknown in " << testName << endl; } } #define RUN(arg) runTest(visitor, #arg, &arg) * Each TestCase is just a series of external assertions; to make this simpler we can define a little macro to stream failing assertions to the visitor: #define TEST(arg) if (!(v &= (arg))) v() << " FAILED: " << #arg << endl; * Then you just write a 2 line python or perl script to regex out the _Foo and testBar names and build an exe or dll from them; wrap that in a MakeIt module, and voila, one of the simplest unit testing suites around. And if you want to make your output pretty looking, just borrow the TestVisitor from CppUnit and season to taste. * Oh yeah, forgot to say that the TestVisitor here exposes an ostream via an operator()(). Hey, it's a lot simpler than trying to derive it. As you can see, it's really not a big deal if you don't make some kind of LanguageLawyer fuss over it like on UnitTestingNonPublicMemberFunctions. Geesh. ''I really like this page. I wish I had been smart enough to do this when I was doing C++. I think calling UnitTestingNonPublicMemberFunctions a "LanguageLawyer fuss" is a bit strong. To me, a LanguageLawyer fuss involves PartialTemplateInstantion, not deciding whether or not to test private member functions. By the way, do you test private member functions? -- WayneConrad'' What private member functions? I rely on soft language encapsulation and make all the C++ classes structs - all public to other C++, all private otherwise. Accessors, phooey. '' Have you published anything with source that shows the AlternateHardAndSoftLayers pattern in action? -- WayneConrad'' I haven't, and to tell the truth I'm still trying to formalize the concept of SoftLanguageEncapsulation. But check out http://cxx.sourceforge.net for a very good place to start. --PeterMerel ---- Actually you should avoid names which begin with an underline, especially if it is followed by a capital. They are reserved for the implementation. Eg struct _Foo is not conforming C++; it invokes undefined behaviour. Names ending with an underline are OK - eg struct Foo_. -- DaveHarris ''Dig it. Will change it.'' ---- Why do you need the visitor? Why are you so against inheritance here? It sounds like the test case will get linked into the final executable - do you use conditional compilation to avoid that? It seems you have to use the preprocessor a lot. I don't see how this solves the problem of UnitTestingNonPublicMemberFunctions. The unit test doesn't get access to private member functions just because it is in the same compilation unit. -- DaveHarris See comments on RefactoringWithCeePlusPlus. I'm still trying to adsorb Peter's AlternateHardAndSoftLayers pattern, but I think it gets around the problem by not having any private member functions. -- WayneConrad Are we saying we're not really writing in C++, but in some other language implemented on top of C++, so it doesn't matter that the C++ is badly structured? I don't think this is what people usually mean by C++ development. -- DaveHarris ---- CategoryTesting