views:

582

answers:

7

Is anyone aware of extensions to CppUnit that can be used to make assertions on a test by test basis concerning memory leaks.

i.e. CPPUNIT_ASSERT_NO_LEAKS()?

Essentially, I want to be able to fail specific tests when the execution of the test results in leaked memory.

A: 

No idea of that, but you could use something like the Fluid Studios Memory Manager code and hook that in yourself with some tweaking. Either that or compile it into your test application and then have a script that runs the application once for each test and collate the memory tracking results.

Daemin
+2  A: 

If you're running on Linux, you could run your tests with memcheck.

The Client Requests section of the manual describes several useful macros, of which one is noted as being useful for testing:

VALGRIND_COUNT_LEAKS: fills in the four arguments with the number of bytes of memory found by the previous leak check to be leaked, dubious, reachable and suppressed. Again, useful in test harness code, after calling VALGRIND_DO_LEAK_CHECK.

The macro is defined in memcheck.h (likely in /usr/include/valgrind), and the sequence you want will resemble

unsigned long base_definite, base_dubious, base_reachable, base_suppressed;
VALGRIND_DO_LEAK_CHECK;
VALGRIND_COUNT_LEAKS(base_definite, base_dubious, base_reachable, base_suppressed);
// maybe assert that they're zero!

// call test

unsigned long leaked, dubious, reachable, suppressed;
VALGRIND_DO_LEAK_CHECK;
VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
CPPUNIT_ASSERT_EQUAL(base_leaked, leaked);
// etc.

Repeating that for every test would be a pain, so you might write macros of your own or, even better, a specialized TestRunner.

Greg Bacon
This does not fail a specific test based on memory leaks...
Jeremy Mayhew
Thanks, I should have been clearer. Revised!
Greg Bacon
+3  A: 

CPPUNIT doesn't have memory leak checks support by default.

The project has been recontinued now (it was stopped for a long time) and this may be a feature of CPPUNIT2, you can propose (or write) to the authors.

If you're looking for a Unit test framework with memory leak detection support you can try looking at CppUTest. It is the project used by Martin Fowler and Bob Martin on some TDD courses. It is pretty good.

Edison Gustavo Muenz
CppUTest is something I haven't seen before...thanks! It looks like there is some rudimentary support for memory testing there. Looking into CppUnit 2 docs now...
Jeremy Mayhew
A: 

Run your unit tests with valgrind. The unit test framework which I use allows you to run one or more individual unit tests so you can detect which one is causing the leak.

Cayle Spandon
+1  A: 

On Windows it would be a pretty simple matter of using some calls to the debug heap to get CppUnit to act on this information using _CrtMemCheckpoint() and _CrtMemDifference():

There are drawbacks:

  • you'd have to place something manually at the start of the test to get the checkpoint (maybe there's a way to integrate that into CppUnit somehow)
  • it's Windows only (there's probably something similar on the various other platforms)
  • it'll only work for builds with the Debug CRT
Michael Burr
A: 

I know it's not CppUnit, but boost::test can do memory leak detection.

From http://www.boost.org/doc/libs/1_39_0/libs/test/doc/html/execution-monitor/user-guide.html:

void detect_memory_leaks( bool on_off );

void break_memory_alloc( long mem_alloc_order_num );

veroxii
This piece from the linked page should be noted:"Unfortunately this feature is, at the moment, implemented only for the Microsoft family of compilers (and Intel, if it employs Microsoft C Runtime Library). Also it can not be tuned per instance of the monitor and is only triggered globally and reported after the whole program execution is done. In a future this ought to be improved."
DevSolar
+1  A: 

Where I work we build our unit tests with purify. Then our continuous integration platform pulls both the number of testcases that succeeded/failed and the number of leaked bytes (+ lint and coverity results) and shows it on a web page. I can highly recommend doing it this way.

Sorry for not providing the solution you wanted.

tombjo