Archive for the ‘DUnit’ Category
Posted by jpluimers on 2021/08/05
Steps:
- Add the conditional define
FASTMM to your project
- Ensure you have
$(BDS)\source\DUnit\src in your search path in your project (as otherwise Delphi will pick the pre-built TestFramework.dcu file which was compiled without the FASTMM conditional define)
- Inside a test method, or the
SetUp method of a class, set FailsOnMemoryLeak to True
- If the
SetUp method of the class allocates memory, ensure the TearDown de-allocates it. Otherwise you will have leaks:
- DUnit will check memory differences from the start of the
SetUp until the end of the TearDown
- DUnit will not take into account what is freed in the
destructor or by automatic finalization after the destructor!
- Re-build your application (otherwise the DUnit
TestFramework unit will not take into account the FASTMM conditional define)
Depending in your test framework, FailsOnMemoryLeak might be by default be False or True:
- TestInsight by default has
FailsIfMemoryLeaked set to True for the root test suite (which is then applied to FailsOnMemoryLeak of any test method).
procedure RunRegisteredTests(const baseUrl: string);
var
suite: ITestSuite;
result: TTestResult;
listener: ITestListener;
begin
suite := RegisteredTests;
if not Assigned(suite) then Exit;
result := TTestResult.Create;
result.FailsIfNoChecksExecuted := True;
result.FailsIfMemoryLeaked := True;
listener := TTestInsightListener.Create(baseUrl, suite.CountEnabledTestCases);
result.AddListener(listener);
try
suite.Run(result);
finally
result.Free;
end;
end;
- Console DUnit runners (Text, or XML) by default have
FailsIfMemoryLeaked set to False.
- GUI DUnit runner has
FailsIfMemoryLeaked depending on the options:

DUnit source differences
Note that recent Delphi versions (I think XE and up) ship with almost the same sources as https://sourceforge.net/code-snapshots/svn/d/du/dunit/svn/dunit-svn-r44-trunk.zip, with these Embarcadero changes:
- all SVN timestamps are based on time zone -0400 instead of +0000:
$Date: 2008-04-24 07:59:47 -0400 (Thu, 24 Apr 2008) $
$Date: 2008-04-24 11:59:47 +0000 (Thu, 24 Apr 2008) $
- Embarcadero removed:
- all comment lines having
TODO in them
- all files of types
.dof, .cfg, and.wmz
- the files
NGUITestRunner.nfm and NGUITestRunner.pas
- the file
/etc/usermap
- the directory trees
/private and /projects
- Embarcadero changed
- file
/src/versioninfo.res from 9.3.0 to 9.2.1 (which is odd, as all files are from 9.3.0)
- unit
TextTestRunner to support:
- CLR (used last in Delphi 2007)
FailureCount
ErrorCount
IndentLevel
PrefixChars
- conditional defines
ADDITIONAL_INFO, BASIC_INFO
- output of
UnitName
- unit
TestExtensions to support:
- CLR (used last in Delphi 2007)
- conditional defines
ANDROID_FIXME and LINUX
- compiler directive
LEGACYIFEND
GUITestRunner.dfm to have ResultsView: TListView property Height value 45 instead of 39
- the below methods to use
ReturnAddress in stead of CallerAddr:
TGUITestCase.FindControl
TGUITestCase.Click
TGUITestCase.EnterKeyInto
TGUITestCase.EnterTextInto
TGUITestCase.Show
TGUITestCase.CheckTabTo overloads
TGUITestCase.CheckFocused overloads
TGUITestCase.CheckEnabled overloads
TGUITestCase.SetFocus overloads
TGUITestCase.CheckVisible overloads
- method
TGUITestRunner.RunTest
- from
class procedure TGUITestRunner.RunTest(test: ITest);
begin
with TGUITestRunner.Create(nil) do
begin
try
suite := test;
ShowModal;
finally
Free;
end;
end;
end;
- to
class procedure TGUITestRunner.RunTest(test: ITest);
var
GUI :TGUITestRunner;
begin
Application.CreateForm(TGUITestRunner, GUI);
with GUI do
begin
try
suite := test;
ShowModal;
finally
Free;
end;
end;
end;
- unit
GUITestRunner:
- from
procedure RunTest(test: ITest);
begin
with TGUITestRunner.Create(nil) do
begin
try
Suite := test;
ShowModal;
finally
Free;
end;
end;
end;
- to
procedure RunTest(test: ITest);
var
GUI :TGUITestRunner;
begin
Application.CreateForm(TGUITestRunner, GUI);
with GUI do
begin
try
Suite := test;
if Suite <> nil then
ShowModal;
finally
Free;
end;
end;
end;
- method
TGUITestRunner.SetUp not to set SubItems[0] := ''; when there is no test suite.
- method
TGUITestRunner.FormCreate to use FormatSettings.TimeSeparator instead of TimeSeparator.
- unit TestFramework to support:
HPPEMIT
LEGACYIFEND
CLR and _USE_SYSDEBUG_
AUTOREFCOUNT
NEXTGEN
ANDROID
- the
RunCountAttribute and RunCount support
- a
CheckEquals overload for uint64
- a
CheckNotEquals overload for TCharArray
CheckCircularRef
CompareFloatRelative
NotSameErrorMessage with WideString arguments instead of string
- a
TestDataDir function
ReturnAddress for older compilers
- a new unit
DUnitTestRunner
- a new
Makefile file
- a new UnitTests.log file
–jeroen
Posted in Conference Topics, Conferences, Delphi, Development, DUnit, Event, FastMM, Software Development, TestInsight | 1 Comment »
Posted by jpluimers on 2021/04/07
From a check-in a while ago, when some Delphi versions complained about CallerAddr having been replaced by ReturnAddress and other versions not understanding ReturnAddress, but having CallerAddr.
The code in the [WayBack] gist and on [WayBack] BitBucket:
ReturnAddressUnit to provide ReturnAddress to Delphi versions not supporting it, and prevent CallerAddr warnings for Delphi versions having ReturnAddress. See https://bitbucket.org/jeroenp/wiert.me/src/…/Native/Delphi/Library/RTL/ReturnAddressUnit.pas
Basically the code maps a variable having a variable ReturnAddress that is a function reference returning a pointer to a function and redirects to CallerAddr when there is no ReturnAddress available. This is the case for anything below Delphi XE2, and avoids W1000 Symbol 'CallerAddr' is deprecated: 'Use ReturnAddress' for Delphi XE2 and up
It is an extract from [WayBack] dunit-extension/TestCaseExtension.pas at master · fabriciocolombo/dunit-extension · GitHub.
There is more interesting code in [WayBack] GitHub – fabriciocolombo/dunit-extension: Extended DUnit TestCase provides assertions to the types Date, Enumerator, Double, and other types, and a class to help run tests with output as XML, text and GUI mode and even more in [WayBack] fabriciocolombo (Fabricio Colombo) · GitHub , which are on my list of things to play with in the future.
Some more [WayBack] commits are at [WayBack] GitHub – cesarliws/dunit-extension (more on [WayBack] Cesar Romero tomorrow).
I think the code from Fabricio is inspired by [WayBack] ZeosLib/TestFrameWork.pas at master · svn2github/ZeosLib · GitHub as it uses the same HAS_BUILTIN_RETURNADDRESS define.
The code by Fabricio is smarter though.
Via: “Delphi” “CallerAddr” “ReturnAddress” – Google Search
–jeroen
Read the rest of this entry »
Posted in Delphi, Development, DUnit, Software Development | Leave a Comment »
Posted by jpluimers on 2021/03/17
Reminder to self: experiment with [WayBack] A DUnit Folder Iterator Extension – The Art of Delphi Programming.
This could be extended to virtual folders, allowing many integration tests to be run depending on some configuration hierarchy defined in a folder structure.
–jeroen
Posted in Conference Topics, Conferences, Delphi, Development, DUnit, Event, Software Development, Unit Testing | Leave a Comment »
Posted by jpluimers on 2016/12/20
Posted in Delphi, Delphi 10 Seattle, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, DUnit, Software Development | Leave a Comment »
Posted by jpluimers on 2016/09/29
On my TODO list.
References:
This in order to get rid of MSXML dependencies in cross platform Delphi development.
–jeroen
Posted in Continua CI, Continuous Integration, Delphi, Development, DUnit, Software Development | 2 Comments »
Posted by jpluimers on 2014/03/03
When writing the Spring4D unit tests for GetTypeSize to include as many TTypeKind values, I came across a few types that either did not compile, or were not supported by TypeInfo. I listed them below as I could not find them in the documentation.
I included a test named Test_EnsureAllTTypeKindsCoveredByCallsTo_Test_GetTypeSize_ that verifies that all TTypeKind values except tkUnknown are covered. So future extensions of TTypeKind will make the tests fail.
As a side issue, I really wanted to know if tkUnknown could be emitted by the compiler. It can sort of, for instance by defining discontiguous enumerations, but are incompatible with TypeInfo as well.
Types that do not compile at all: Read the rest of this entry »
Posted in Agile, Delphi, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 8, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Development, DUnit, Software Development, Unit Testing | 2 Comments »
Posted by jpluimers on 2010/09/08
Recently, I was at a client where in a project strings had to be split from:
'FI-150 1U; FI-049-I L=20 MM;LET OP LASVORM'
Into:
'FI-150 1U'
'FI-049-I L=20 MM'
'LET OP LASVORM'
At first sight, this looks simple: Semicolon Separated Values and you are done.
Not so fast Mr Smart Alec: watch the optional spaces!
The best thing for problems like these is to start with an empty implementation that some units tests covering it.
I use DUnit for Delphi unit testing.
Unit testing should go with code coverage, but there are few Delphi code coverage articles.
I’ll get into code coverage later on, as I’m working with two of the code coverage people to get this to work nicely with Delphi 2010.
Mock objects can be a good addition to unit testing too, so in a future article, I will cover using mock objects with Delphi.
Read the rest of this entry »
Posted in Agile, Conference Topics, Conferences, Delphi, Development, DUnit, Event, Software Development, Unit Testing | 8 Comments »