Question

Hey there i have a problem with my Unit Testing in Delphi XE3 i have a project that consist of 1 MDIForm and allot of MDIChild forms then problem is that when i run test on my MDIChild forms i get this error:

TestAllDataSrouces: EInvalidOperation
at  $0064346F
SetUp FAILED: Cannot create form. No MDI forms are currently active

my Setup method looks like this:

procedure TestTCustomerCard.SetUp;
begin
  FCustomerCard :=  TCustomerCard.Create(Application);
end;

what can i do to solve this error? so far i tried:

FCustomerCard :=  TCustomerCard.Create(Application.MainForm);

FCustomerCard :=  TCustomerCard.Create(nil);

And

procedure TestTCustomerCard.SetUp;
var
  a : TForm;
begin
  a := TForm.Create(nil);
  a.FormStyle := fsMDIForm;
  FCustomerCard :=  TCustomerCard.Create(a);
end;

and my test is:

procedure TestTCustomerCard.TestAllDataSrouces;
var
  I: Integer;
begin
  for I := 0 to FCustomerCard.ComponentCount-1 do
  begin
    if (FCustomerCard.Components[i] is TcxLookupComboBox) then
    begin
      Check(TcxLookupComboBox(FCustomerCard.Components[i]).Properties.ListSource = nil,'Error no ListSource, Lookup: '+TcxLookupComboBox(FCustomerCard.Components[i]).Name+' Parent: '+TcxLookupComboBox(FCustomerCard.Components[i]).Parent.Name);
    end;
    if (FCustomerCard.Components[i] is TcxDBTextEdit) then
    begin
      Check(TcxDBTextEdit(FCustomerCard.Components[i]).DataBinding.DataSource = nil,'Error No DataSet, Text Edit: '+TcxDBTextEdit(FCustomerCard.Components[i]).Name+' Parent: '+TcxDBTextEdit(FCustomerCard.Components[i]).Parent.Name);
    end;
    if (FCustomerCard.Components[i] is TcxGridDBTableView) then
    begin
      Check(TcxGridDBTableView(FCustomerCard.Components[i]).DataController.DataSource = nil,'Error no Data Source, DB Grid View: '+TcxGridDBTableView(FCustomerCard.Components[i]).Name);
    end;
  end;
end;

Demo Project: Here

Was it helpful?

Solution

What you are doing is more like a functional or integration test. You are checking that your UI is correctly set up. That kind of test is different from a unit test.

Unit tests are supposed to check that if you give a module certain inputs, then they produce certain outputs. Unit tests are localized. They are meant to test the behaviour of a unit independently from other units. A UI specifically depends on other units. They take data from input devices and operate on databases and on the whole have quite complicated set of dependencies. That makes them a bad target for unit testing.

Take a look at this question - Unit tests vs Functional tests

To do the kind of testing you want, it is probably best to make your own tool that can set up the environment correctly and perform the test.

OTHER TIPS

The error message pinpoints the problem. If you need an MDI child form, it must have an MDI parent form. And that parent form must be the main form of your program. Hard to achieve in a DUnit project. Your solutions appear to be:

  • Make the main form of your program be an MDI main form. I think that will be tricky to achieve.
  • Make your form under test not be an MDI child form.
  • Find a way to test that does not require instantiation of this form.

I have encountered the same problem, and I decided to implement advice of David Heffernan and "Make your form under test not be an MDI child form".

Here I will describe how I could reach this. I have made all changes in my testcase unit.

  1. Make test form that inherits original MDI child form

    type TTestCustomerCard = class(TCustomerCard) end;

    Add this just before your test case class.

  2. Copy dfm file or the form, say CustomerCard.dfm, to TestCustomerCard.dfm

  3. Open TestCustomerCard.dfm in any text editor, delete line

    FormStyle = fsMDIChild (because fsNormal is default value),

    change first line object CustomerCard: TCustomerCard

    to object TestCustomerCard: TTestCustomerCard

  4. Add directive {$R TestCustomerCard.dfm }

  5. In your SetUp method instead of

    FCustomerCard := TCustomerCard.Create(Application);

    write

    FCustomerCard := TTestCustomerCard.CreateNew(Application); InitComponentRes( 'TTESTCUSTOMERCARD', FCustomerCard );

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top