Delphi GUI测试和模态窗体
在
delphiXtreme的这篇有趣的博文中,我阅读了关于DUnit内置的GUI测试功能(基本上是单元GUITesting中定义的替代测试用例类TGUITestCase,它具有多个用于在GUI中调用操作的实用功能).我很高兴,直到我注意到它不适用于模态形式.例如,如果第一个按钮显示一个模态配置窗体,以下序列将不起作用:
Click ('OpenConfigButton'); Click ('OkButton'); 第二次点击仅在模态窗体关闭时执行,我必须手动执行. 我不太了解模态在后台如何工作,但必须有一些方法来规避这种行为.天真地,我想以某种方式在线程中执行ShowModal,以使“主线程”保持响应.现在我知道在一个线程中运行ShowModal可能会弄乱一切.有什么办法吗任何方式来规避ShowModal的阻塞性质?有没有人在Delphi中进行GUI测试? 我了解外部工具(来自QA或其他),我们使用这些工具,但这个问题是关于IDE内的GUI测试. 谢谢! 解决方法
您无法通过调用ShowModal来测试模态窗体;因为正如你们正确地发现的那样,这样会导致您的测试用例代码“暂停”,而模态窗体等待用户交互.
这样做的原因是,ShowModal将切换到“辅助消息循环”,直到表单关闭后才会退出. 然而,模态仍然可以被测试. >使用正常的Show方法显示通常的模态窗体. 通过设置模态结果通常关闭模态窗体. 警告 您可以使用此技术通过非模态显式显示来测试特定的模态形式.但是,任何显示模态表单的代码(例如“错误对话框”)将暂停您的测试用例. 甚至你的示例代码:点击(‘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; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |