DUnit GUI Validation: Can I force an “application” to another “form”?

I am trying to run the GUI unit test with DUnit for an application whose main form creates dynamic frames for itself. I was able to create the main form of the application for testing as a form in the test case and access its menu items, etc.

The problem occurs when an application tries to create a frame dynamically. The reading of the frame resource occurs to such an extent that it needs a window handle (in my case, setting the title of the tab sheet). Here it goes from TWinControl.GetHandle to TWinControl.CreateWnd and to TCustomFrame.CreateParams.

This CreateParams code says:

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

There is a difference. When I run the actual application (not in the test), Application.Handle returns a nonzero number, and the thread continues normally. But in the DUnit test application, Application.Handle returns 0. This causes the code in TWinControl.CreateWnd to throw an exception indicating that there is no parent in the frame:

  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 would like to try to get around this problem (and generally, all test problems) without changing the "production" code just because of the tests. Can you give any information on whether I can somehow get the “Application” to do something else or somehow get around this?

If you look at the code, perhaps another workaround scenario might be to try to get the owner (which is my "MainForm" for the application to the test, ie whose descriptor I want to get) to be in csReading in the process of creating this frame in the test, but at least at first glance, it’s not so easy for this to happen.

+6
source share
2 answers

Thanks for all the comments and answers! I believe that I have solved the problem, at least so far. I will summarize my findings and the final situation below (in case someone finds any of this useful).

I have a class decorator class inheriting from TTestSetup, which contains a link to the dummy (main) form that it creates if necessary.

I also found a way to switch Application.MainForm at runtime using this approach: http://www.swissdelphicenter.ch/torry/showcode.php?id=665

In the SetUp method for the test decoder, I first create a dummy form and then set it as the main form of the application (this parameter may not be needed here).

Then I have a test case class (inheriting from TGUITestCase) whose SetUp and TearDown are run for each test. In this SetUp, I create the main form that I am testing, and then set it as the main form of the application. Then after the test in the TearDown test case, I again set the dummy form as the main form of the application and only after this call Close and Free for the main form that I am testing. Otherwise, freeing the form, which is currently Application.MainForm, will terminate the entire DUnit application.

0
source

Instead of getting around the installation method of Application.Handle, you should create TForm and set your frame.parent as 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 applications, frames will have a parent (parent template, usually TForm or TPanel). You are trying to say a frame to run without a parent, which TFrame is not designed to run.

+2
source

Source: https://habr.com/ru/post/909066/


All Articles