2

In our Delphi2007 environment we have a SGLibrary groupproj which contains some 30 bpls. We're just starting out creating unittests for these libraries and are not sure what the most convenient way of organizing the Unittest projects would be.

We are inclined to create a test-executable for each bpl, as this will make compilation an running easy and fast. The test-exe can be set as the active project and Compilation of the bpl can be forced by setting a dependency. It is also easy to run tests, ie by setting the test-executable as the Hostapplication of the bpl.

But the downside is that the library groupproject will be expanded with another 30 items, making it a very large group (why can't we make subgroups in Delpi ???).

The opposite arrangement would be to create 1 test executable which contains all unit-tests but that would create a executable with over a hundred units, and lots of depencies which all have to be compiled before a single test can be run.

So my question ... Does anybody have any suggestions, best practices, or other ideas on how to organize this into a manageable and fast running setup?

Extra consideration: We want to have the possibility to run all tests at once, and of course this will be easier in we put all tests in one executable.

Bascy
  • 2,017
  • 1
  • 21
  • 46

2 Answers2

3

There is a little known feature of DUnit that supports running tests from a dll. You basically create a dunit exe project that has no tests of its own, rather it loads tests from dlls.

Each dll needs to export a single function:

library MyTests;
 
uses
  TestFramework{, add your test units};
 
function Test: ITest;
begin
  result := RegisteredTests;
end;
 
exports
  Test;     
end;

Then you just add test cases to the dll as normal. The tests are automatically registered in each unit's initialization section.

IMHO its a pity this isn't promoted as the standard way of working with DUnit. Most unit testing frameworks for other languages are organized this way. They provide a single test runner executable which dynamically loads test cases from any number of loadable modules.

In addition to letting you break up your tests for easier organization it also allows you to run the same tests under multiple scenarios. Perhaps you want to run your tests using different compiler options for your debug and release builds (or even different versions of the compiler) so you are more confident that the code behaves consistently. You can build multiple dlls from the same source and run them in the same session.

Community
  • 1
  • 1
Kenneth Cochran
  • 11,954
  • 3
  • 52
  • 117
  • 1
    That's new to me too! Thanks for the update. I presume DUnit2 has the same possibilities? – Bascy Feb 21 '11 at 14:43
  • Talking about this with my colleague we even landed on the idea of creating test .bpl's for every .bpl we have in our library and a general "RunTests.exe" that can load the .bpl's as plugins in the executable – Bascy Feb 21 '11 at 19:59
  • Oh man, this is brilliant! I wish I'd known that ages ago :-) Wish I could do more than +1 – Jeroen Wiert Pluimers Feb 23 '11 at 09:55
  • @Bascy Yes, this feature was available before the fork. DUnit2 does a little better job publicizing it. I'm not sure if they've improved it as I haven't tried DUnit2 yet. – Kenneth Cochran Feb 23 '11 at 18:11
2

I'd probably do both, so you end up with this:

  1. all your unit tests, group them by BPL.
  2. a project for each of the units tests for each BPL.
  3. a project with all the tests.

You can use the final project in your continuous integration system, and the former for testing things that are not yet checked in.

This is indeed a large number of projects, a price you pay for being able to improve the quality of your code.

--jeroen

Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154
  • We haven't even thought about doing both :-) but it does have its advantages. But the biggest disadvantage is of course the chance that a newly created Unittest is not added to the integrationTest suite. – Bascy Feb 15 '11 at 15:52
  • 1
    @Bascy for that you need to regularly observe unit testing coverage, for instance by using the tools here: http://stackoverflow.com/questions/531546/measuring-code-coverage-in-delphi – Jeroen Wiert Pluimers Feb 16 '11 at 19:54