Question

Is there a way to write unit tests so that they can be compiled and run both with Delphi and Free Pascal?

There are different unit test frameworks for Delphi and Free Pascal, which causes duplicate work for developers who target both compilers (for example, library and framework developers).

So maybe there is a way, using either the DUnit or the FPCUnit framework and tweak the test case source code (or the framework itself) so that it also works with the other compiler.

So essentially the question is:

  • which framework (DUnit or FPCUnit) can be compiled with both compilers (Delphi and Free Pascal) with as little modifications as possible?

or

  • is there a third framework (Thanks to Arnaud for mentioning TSynTest) which works with Delphi and FPC?
Was it helpful?

Solution

Default unit test framework for Free Pascal is FPCUnit, it has the same design as DUnit but different from it in minor details. You can write common unit tests for FPCUnit and DUnit by circumventing the differences by {$IFDEF FPC}. I just tested FPCUnit, it is a usable framework, and blogged about it.

OTHER TIPS

See this very nice blog article - just fresh meat about FPCUnit testing.

In short, as far as I know, and if you compare to DUnit:

  • Most Check*() methods were renamed Assert*();
  • SetUp / TearDown methods are called per-function in both framework;
  • Some other thinks may vary.

So, I think it could be easy to let FPCUnit "mimics" DUnit, by creating a small wrapper class over FPCUnit implementation, to have the same exact methods than with DUnit. So you may be able to share code between the two targets, and even re-use existing DUnit tests. Such a wrapper class is IMHO much more convenient that using {$ifdef FPC} as other suggested here. Conditional compilation tends to make code hard to debug, verbose, redundant and should be used only if necessary.

Another potential solution could be to use other tests frameworks. Our small TSynTest classes are lighter, but I'm currently converting the framework to FPC. So the same exact code could be used with both compilers. It has some features (like optional logging with fine profiling, and full stack strace on failure) which I would miss from DUnit / FPCUnit. It does not have a GUI nor a Wizard but honestly, as I programmer I prefer plain text that I can include in my technical release documentation easily to testify that no regression occurred.

I just whipped up a sample that works in both DUnit (delphi) and FPCUnit (Freepascal equivalent nearest to DUnit, that happens to ship already "in the box" in lazarus 1.0, which includes freepascal 2.6 ):

A trivial bit of IFDEF and you're there.

unit TestUnit1;

{$IFDEF FPC}
{$mode objfpc}{$H+}
{$ENDIF}

interface

uses
  Classes,
  {$ifdef FPC}
  fpcunit, testutils, testregistry,
  {$else}
  TestFramework,
  {$endif}
  SysUtils;

type
  TTestCase1= class(TTestCase)
  published
    procedure TestHookUp;
  end;

implementation

procedure TTestCase1.TestHookUp;
begin
   Self.Check(false,'value');
end;

initialization
  RegisterTest(TTestCase1{$ifndef FPC}.Suite{$endif});
end.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top