Caves Travel Diving Graphics Mizar Texts Cuisine Lemkov Contact Map RSS Polski
Trybiks' Dive Texts Testing Detecting Memory Leaks with DUnit YAC Software
  Back

List

Charsets

Charts

DBExpress

Delphi

HTML

Intraweb

MSTest

PHP

Programming

R

Rhino Mocks

Software

Testing

UI Testing

VB.NET

VCL

WPF

Detecting Memory Leaks with DUnit
DUnit (the unit testing framework for Delphi) has a nice feature of detecting memory leaks during tests; that is, it checks total allocated memory before and after running a test, and if the second value is greater than the first value, it (optionally) reports a test failure.

To enable this feature in DUnit, use the Fail TestCase if memory leaked option in DUnit's Options menu.

However, you can start getting seemingly invalid test failures - if, during the test, some memory gets allocated, but is freed not in the test itself, but later on, such as on application shutdown.

This often happens when using system calls, third party libraries, or GUIs (though, obviously, it can happen with your own code, too). After all, a common design pattern is to allocate memory in a "lazy" fashion - on the first call to a routine or on the first reference to an object/class that needs additional memory. And memory allocated thus is often freed when the class/unit is unloaded from memory - on application shutdown (in the unit's finalization section, for instance).

For example, let's say that you are testing DB code (using DBExpress and MySQL). In the test case, you create a connection, do some operations on the DB, and then free the connection. Because DBExpress allocates some memory on creation of the first connection and doesn't free it until the application finishes, you get a memory leak:
  procedure TYACDBTests.TestMemory;
  var
    LConnection: TSQLConnection;
  begin
    LConnection := CreateSQLConnection;
    Check(TRUE);
    FreeAndNIL(LConnection);
  end;
The code is quite ok (where CreateSQLConnection creates the object, sets all parameters, and connects to the DB), but the memory "leak" is still there - that is, it will be reported by DUnit...

A possible workaround in such cases is to insert "dummy" code that will force the first allocation before any tests are run, so that during the tests, the needed memory is already allocated (thus accounted for when DUnit checks total allocated memory before the test).

You can place this code in the unit's initialization section, for instance:
  var
    LConnection: TSQLConnection;
  initialization
    LConnection := CreateSQLConnection;
    FreeAndNIL(LConnection);
  end.
Now, the TSQLConnection created in the test case doesn't allocate any more memory, thus DUnit's leak detector stops failing the test.

An easy way to find out scenarios similar to this one (though not bullet-proof) is when a second run of the testing suite doesn't show the memory leak anymore (but, a second run without restarting DUnit after the first run). Then there's a high probability that the first run allocated some memory that is not being allocated anymore on the second run. And that's a good candidate for a solution like the one above, though it's not always that easy to find out what code should be called before our tests...

Top

Comments
Alas!
No comments yet...

Top

Add a comment (fields with an asterisk are required)
Name / nick *
Mail (will remain hidden) *
Your website
Comment (no tags) *
Enter the text displayed below *
 

Top

Tags

Testing

Delphi


Related pages

AssertWasCalled and Methods Called Multiple Times

AssertWas[Not]Called and Object Properties

Rhino Mocks's AssertWasNotCalled

Visual Studio - moving coded UI tests to a new / different project results in null reference exceptions

PrivateObject and Out/ByRef parameters

PrivateObject, WithEvents, and generics

Delphi interfaces... again

Accessing private members of base classes

PrivateObject and WithEvents

Accessing private and protected members - PrivateObject and PrivateType

VS - Test Run Error - "COM object that has been separated from its underlying RCW cannot be used"

Get the TreeViewItem for an Item in a WPF TreeView

Output in MSTest Tests (VS 2010)

Automated WPF tests and "Invalid URI: Invalid port specified."

Checking Property Change Notifications

Checking "Dangling" Event Handlers in Delphi Forms

Rhino Mocks's AssertWasCalled in VB.NET

First steps with Rhino Mocks (in VB.NET)

VS Pending Tests

Drag-n-drop files onto the application window

Intraweb and MaxConnections

A Case for FreeAndNIL

Intraweb as an Apache DSO module

"Device not supported" in Intraweb

Automated GUI Testing

Rounding and precision on the 8087 FPU

SessionTimeout in Intraweb

Using TChart with Intraweb

Unknown driver: MySQL

Automated GUI Testing in VMs

TIdMessage's CharSet

Software Guarantees

Automated Testing of Window Forms

TChart - Missing Labels in Axes

Memory Leaks and Connection Explosions in DBExpress

Controlling Conditional Defines and Compilation Switches

last_insert_id() and DBExpress

Registering Extensions

DBExpress and Thread Safety

Forms as Frames

Checking Dangling Pointers vs. the New Memory Manager

Accessing Protected Members

Objects, interfaces, and memory management in Delphi