views:

379

answers:

1

I've used both CppUnit and boost::test for C++ unittesting. Generally I prefer boost::test, mainly because the auto-test macros minimise the effort to setup tests. But there's one thing I really miss from CppUnit: the ability to register your own "protectors", instances of which automatically wrap all the run tests. (Technically, you install a test "listener", and that can wrap each test in a protector scope).

I've found these invaluable in the past for monitoring unittests for unexpected side effects (e.g checking code hasn't changed the floating-point unit state flags). I can't see any equivalent in the boost::test documentation, although BOOST_FIXTURE_TEST_CASE maybe comes closest.

Any suggestions for how to best achieve the same thing as CppUnit's protectors in boost::test ?

(I haven't really looked into boost::test's implementation yet, but if it's anything like CppUnit it must use something very like protectors itself).

+2  A: 

I've never used CppUnit, so not sure how protectors work. Are you looking for something that wraps individual tests, or the entire test suite?

For the former, you could use fixtures as you mention, but as I understand it, fixtures should be considered "outside" the test. They set up whatever the test needs, and cleans it up afterwards. Any actual error-testing should be in the test itself, but can be easily implemented with RAII. Simply define a class which checks whatever you need in its destructor, and then create a local instance of it at the beginning of the test. Since it is constructed first, it gets destructed last, so it can easily check that the test hasn't modified any unexpected state.

If you want it to check this after all the tests have executed, you probably want global fixtures

jalf
CppUnit Listeners/Protectors give you the convenience of RAII-scoped testing in (or around) each test, but without having to tediously add a line of code to each test. Thanks for the pointers to global fixtures... if there was just some equivalent where the ctor/dtor was invoked for each test run, that'd be perfect, but without it global-replacing all my BOOST_AUTO_TEST_CASE with BOOST_FIXTURE_TEST_CASE and building protector-like checks into the supplied fixture seems like the best bet.
timday
Ah, I think I get it. You want this RAII object wrapped around every single test case in every test suite, without having to explicitly specify it for each test?My best bet would be a simple wrapper macro which expands to BOOST_FIXTURE_TEST_CASE with your protector object inserted on the first line.
jalf
Interesting idea though, sounds like a useful addition. Feel free to suggest it to the Boost library authors ;)
jalf
timday