Delphi GUI测试和模态窗体

前端之家收集整理的这篇文章主要介绍了Delphi GUI测试和模态窗体前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
delphiXtreme的这篇有趣的博文中,我阅读了关于DUnit内置的GUI测试功能(基本上是单元GUITesting中定义的替代测试用例类TGUITestCase,它具有多个用于在GUI中调用操作的实用功能).我很高兴,直到我注意到它不适用于模态形式.例如,如果第一个按钮显示一个模态配置窗体,以下序列将不起作用:
Click ('OpenConfigButton');
Click ('OkButton');

第二次点击仅在模态窗体关闭时执行,我必须手动执行.

我不太了解模态在后台如何工作,但必须有一些方法来规避这种行为.天真地,我想以某种方式在线程中执行ShowModal,以使“主线程”保持响应.现在我知道在一个线程中运行ShowModal可能会弄乱一切.有什么办法吗任何方式来规避ShowModal的阻塞性质?有没有人在Delphi中进行GUI测试?

我了解外部工具(来自QA或其他),我们使用这些工具,但这个问题是关于IDE内的GUI测试.

谢谢!

解决方法

您无法通过调用ShowModal来测试模态窗体;因为正如你们正确地发现的那样,这样会导致您的测试用例代码“暂停”,而模态窗体等待用户交互.

这样做的原因是,ShowModal将切换到“辅助消息循环”,直到表单关闭后才会退出.

然而,模态仍然可以被测试.

>使用正常的Show方法显示通常的模态窗体.
>这允许您的测试用例代码继续,并模拟用户操作.
>这些动作和效果可以正常测试.
>您将需要一个额外的测试,特别是模态形式:

通过设置模态结果通常关闭模态窗体.
>事实上,你使用“显示”表示不会通过设置模态结果来关闭窗体.
>这是很好的,因为如果你现在模拟点击“确定”按钮…
>您可以简单地检查ModalResult是否正确.

警告

您可以使用此技术通过非模态显式显示来测试特定的模态形式.但是,任何显示模态表单的代码(例如“错误对话框”)将暂停您的测试用例.

甚至你的示例代码:点击(‘OpenConfigButton’);导致ShowModal被调用,不能以这种方式进行测试.

解决这个问题,您需要将“show命令”注入到应用程序中.如果您对依赖注入不了解,我建议您使用Misko Hevery的“清洁代码会话”视频.然后在测试时,您将注入不会显示模态窗体的“show命令”的合适版本.

例如,如果在单击“确定”按钮时验证失败,您的模态窗体可能会显示错误对话框.

所以:

1)定义一个接口(或抽象基类)来显示错误消息.

IErrorMessage = interface
  procedure ShowError(AMsg: String);
end;

2)您正在测试的表单可以持有注入的接口引用(FErrorMessage:IErrorMessage),并在验证失败时使用它来显示错误.

procedure TForm1.OnOkClick;
begin
  if (Edit1.Text = '') then
    FErrorMessage.ShowError('Please fill in your name');
  else
    ModalResult := mrOk; //which would close the form if shown modally
end;

3)使用/注入生产代码的IErrorMessage的默认版本将照常显示消息.

4)测试代码将注入一个模拟版本的IErrorMessage,以防止您的测试被暂停.

5)您的测试现在可以执行通常显示错误消息的情况.

procedure TTestClass.TestValidationOfBlankEdit;
begin
  Form1.Show; //non-modally
  //Do not set a value for Edit1.Text;
  Click('OkButton');
  CheckEquals(0,Form1.ModalResult);  //Note the form should NOT close if validation fails
end;

6)您可以将模拟IErrorMessage进一步实际验证消息文本.

TMockErrorMessage = class(TInterfaceObject,IErrorMessage)
private
  FLastErrorMsg: String;
protected
  procedure ShowError(AMsg: String); //Implementaion trivial
public
  property LastErrorMsg: String read FLastErrorMsg;
end;

TTestClass = class(TGUITesting)
private
  //NOTE!
  //On the test class you keep a reference to the object type - NOT the interface type
  //This is so you can access the LastErrorMsg property
  FMockErrorMessage: TMockErrorMessage;
  ...
end;

procedure TTestClass.SetUp;
begin
  FMockErrorMessage := TMockErrorMessage.Create;
  //You need to ensure that reference counting doesn't result in the
  //object being destroyed before you're done using it from the 
  //object reference you're holding.
  //There are a few techniques: My preference is to explicitly _AddRef 
  //immediately after construction,and _Release when I would 
  //otherwise have destroyed the object.
end;

7)现在较早的测试成为:

procedure TTestClass.TestValidationOfBlankEdit;
begin
  Form1.Show; //non-modally
  //Do not set a value for Edit1.Text;
  Click('OkButton');
  CheckEquals(0,Form1.ModalResult);  //Note the form should NOT close if validation fails
  CheckEqulsString('Please fill in your name',FMockErrorMessage.LastErrorMsg);
end;
原文链接:https://www.f2er.com/delphi/102776.html

猜你在找的Delphi相关文章