blog.vi-kan.net One thought after another

DUnit: Loading tests from dll’s

I wanted to split all my unittests for a project into separate packages to keep tings nice and clean. DUnit comes with a unit called TestModules.pas which helps you do that.

The unit contains three public methods:

function LoadModuleTests(LibName: string) :ITest;
procedure RegisterModuleTests(LibName: string);
procedure UnloadTestModules;

The LoadModuleTests( )-function, dynamically loads the given library (dll or dtl files), and returns an interface to the tests defined within. RegisterModuleTests( ) does the same, but also calls RegisterTest( ) with the interface from the library.

There is one requirement that the library has to satisfy. It must export a function named ‘Test’ that returns a ITest-interface. Following is a basic project file showing how this can be done:

library OurUnitTests;

uses
  TestFramework;

function Test: ITest;
begin
  result := RegisteredTests;
end;

exports
  Test name 'Test';

end;

The Test( )-function simply returns the result from the RegisteredTests( ) method from the TestFramework-unit. RegisteredTests( ) returns a ITestSuite containing all the test classes registered.

Here’s a samle project file that loads all dll-files from the executables folder, and runs all test through the GUITestRunner:

program RunTests;
uses
  Forms,
  TestFramework,
  GUITestRunner,
  TestModules,
  SysUtils,
  Windows,
  JclFileUtils,
  classes,
  Dialogs
  ;

  {$R *.RES}

procedure LoadTests;
var
  filelist: TStringList;
  str: string;
begin
  filelist := TStringList.Create;
  try
    BuildFileList('*.dll', faAnyFile, filelist);

    for str in filelist do
    begin
      try
        RegisterModuleTests(str)
      except
        on E: Exception do
          ShowMessage(e.Message);
      end;
    end;
  finally
    filelist.free;
  end;
end;

begin
  Application.Initialize;

  LoadTests;
  GUITestRunner.RunRegisteredTests;
  UnloadTestModules;
end.

The BuildFileList( ) method comes from JCL, and simply fills a TStringList with filenames from the given mask. As I said, this is a very basic project, but it shows how to use the TestModules-unit to dynamically load tests. This can easily be expanded to a more flexible solution. You could use command parameters to control what folder should be searched for libraries, or what testrunner should be used, GUI or XML or custom runner.

comments powered by Disqus