Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DUnit GUI Testing: Can I force 'Application' to a different "form"?

I'm trying to run a GUI unit test with DUnit to an application whose mainform creates dynamically frames to itself. I've been able to create the application-to-test's mainform as a form in the test case and access its menu items etc.

The problem comes when the application tries to create a frame dynamically. The frame's resource reading comes to a point where it needs the window handle (in my case, setting the caption of a tab sheet). Here it goes from TWinControl.GetHandle to TWinControl.CreateWnd and to TCustomFrame.CreateParams.

In this CreateParams, the code says:

  if Parent = nil then
    Params.WndParent := Application.Handle;

This is where the difference occurs. When I run the actual application (not in the test), the Application.Handle here returns a non-zero number and the flow continues ok. But in the DUnit test application, the Application.Handle here returns 0. This causes the code in the TWinControl.CreateWnd to raise an exception telling that the frame does not have a parent:

  with Params do
  begin
    if (WndParent = 0) and (Style and WS_CHILD <> 0) then
      if (Owner <> nil) and (csReading in Owner.ComponentState) and
        (Owner is TWinControl) then
        WndParent := TWinControl(Owner).Handle
      else
        raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);

I'd like to try to get around this problem (and in general, all test problems) without modifying the "production" code just because of the tests. Can you provide any clues on whether I could somehow force the "Application" to something else, or in some other way work around this?

Looking at the code, a possible other workaround scenario might be to try to get the owner (which is my "MainForm" of the application-to-test, i.e. whose handle I'd want to get) to be in csReading state while doing this frame creation in the test, but at least initially it doesn't seem so straightforward to get this to happen either.

like image 620
DelphiUser Avatar asked Feb 22 '12 10:02

DelphiUser


Video Answer


1 Answers

Instead of working around a way to set Application.Handle, you should create a TForm, and set your frame.parent to be that TForm.

//Dunit Test Scaffolding code...Set up a workable environment for the test:
aForm := TForm.Create(nil);
aFrame := TFrame.Create(aForm);
aFrame.Parent := aForm;

In real apps, frames will have a parent (be parented to a window, a TForm or TPanel usually). You are trying to tell a frame to run without a parent, which TFrame is not designed to do.

like image 109
Warren P Avatar answered Oct 10 '22 23:10

Warren P