2

I created a library in delphi using Embarcadero XE2, and i want to test it's functions and procedures, but there are too many of them (more than 50). I would like to create a form to test these my library, with a list of functions on the left (with an options-like treeview), and with optional text boxes and a fireing button on the right of the form. I found a few treeview tutorial on the web, but they visualised databases with the treeview.

Treeview is not necessary, any possible enumeration of functions wolud be great.

Is there any straightforward method to test so many functions? Is there an easier way to implement this test(form)?

My library as a refractor for OpenOffice.org API, and it consists mainly of procedures, not functions, wich are hard to test with unit testing framework, and it would be great to create a GUI to test this class, because I have to check manually how they work. Is there any solution for this kind of test?

fodma1
  • 3,485
  • 1
  • 29
  • 49

2 Answers2

6

You could do this, but it's really the wrong approach. You're reinventing the wheel, and setting yourself up for missing testing things because you can't consistently and reliably repeat the tests.

Testing should be repeatable, and should always exercise as many possible testing options that can be tested each time something changes, to make sure that you don't introduce a bug (or put back in a bug you've fixed before), and to allow you to easily support new options or parameters or values.

You should use DUnit (Delphi unit testing), included in Delphi for several versions now (and available for earlier versions at SourceForge), which allows you to automate the testing process, and includes a TreeView that shows the test setups (called Suites), the individual tests that make up that suite, and the results of each test. It allows you to test things that should work and things that shouldn't (and make sure they don't), and repeat tests consistently so you don't miss anything. It also gives you information about any test that fails, along with information that helps you find (and fix) the failure condition.

In versions of Delphi that include DUnit already (which I believe is anything starting with Delphi 2007 and later), use File->New->Other->Unit Tests->Test Project to create the shell. For non class based testing, create another new unit and set up the tests manually. Here's a shell for you to begin with, with tests for two meaningless functions:

unit MyFunctionsTests;
{
  Delphi DUnit Test Case Skeleton Unit
}
interface

uses
  TestFramework, MyFunctions;

type
  // Test methods for MyFunctions unit
  // In the real world, you'd create separate test cases,
  // one for tests that should pass and one for tests that
  // should fail, and run them separately or in succession.
  // This is just a simple shell.
  TTestMyFunctions = class(TTestCase)
  strict private
  public
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure TestFunctionOne;
    procedure TestFunctionTwo;
  end;

implementation

procedure TTestMyFunctions.Setup;
begin
  // Do any necessary initializations, set variables, etc.
end;

procedure TTestMyFunctions.TearDown;
begin
  // Free any objects, release any memory, etc. here
end;

procedure TTestMyFunctions.TestFunctionOne;
begin
  // FunctionOne takes two integers and adds them, and
  // returns the sum
  CheckTrue(FunctionOne(1, 1) = 2);  // Test success
  CheckFalse(FunctionOne(2, 2) = 5); // Test failure
end;

procedure TTestMyFunctions.TestFunctionTwo;
begin
  CheckEqualsString('AB', FunctionTwo('A', 'B')); // Success
  CheckFalse(FunctionTwo('B', 'A') = 'AB');       // Failure
end;

initialization
  // Register any test cases with the test runner
  RegisterTest(TTestMyFunctions.Suite);
end.

Use Project->Add to Project, and add your unit (MyFunctions.pas) and your new test case unit (MyFunctionTests.pas in the above shell). It should look something like this:

program MyFunctionUnitTests;
{

  Delphi DUnit Test Project
  -------------------------
  This project contains the DUnit test framework and the GUI/Console test runners.
  Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options
  to use the console test runner.  Otherwise the GUI test runner will be used by
  default.

}

{$IFDEF CONSOLE_TESTRUNNER}
{$APPTYPE CONSOLE}
{$ENDIF}

uses
  DUnitTestRunner,
  MyFunctions in '..\MyFunctions.pas',
  MyFunctionsTests in 'MyFunctionsTests.pas';

{$R *.RES}

begin
  DUnitTestRunner.RunRegisteredTests;
end.

Now run the project, and in the window that appears click the green Play button (like the run button in the Delphi IDE) or hit F9. The treeview will show you the results (green for passed, red for failed) of the tests. If a test fails, you can view the error information for that test at the bottom of the window. (If you can't, use the View window to display the errors.)

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Thank you for the detailed answer, I think it's really helpful. Though I have problem with it. I use my library as a refractor for OpenOffice.org API, and it consists mainly of procedures, not functions, wich are hard to test with this 'Dunit' shell, and that's why I tought it would be great to create a GUI to test this class, because I have to check manually how they work. Is there any solution for this kind of test? – fodma1 Jun 02 '13 at 12:42
  • I don't understand your question. If the procedure in your app can be tested by you, how do you determine if it worked or not? If you can tell success or failure, there's most likely a way to automate that testing. "Checking manually" usually means you save something that succeeds, and then use it to compare against the automated test to judge whether your test passes or not. – Ken White Jun 02 '13 at 13:57
3

Use Dunit instead. Really, you should. That's what it's for. http://dunit.sourceforge.net/README.html

There is a little bit of a learning curve, but once you get it, it'll be "aahhhh!"

Chris Thornton
  • 15,620
  • 5
  • 37
  • 62