Delphi GUI 测试和模态表单
在关于 delphiXtreme 的这篇有趣的博客文章中,我了解了 DUnit 的内置 GUI 测试功能(基本上是替代测试用例类< code>TGUITestCase 在单元 GUITesting
中定义,它具有多个用于调用 GUI 中操作的实用函数。我对它非常满意,直到我注意到它不适用于模态形式。例如,如果第一个按钮显示模态配置表单,则以下序列将不起作用:
Click ('OpenConfigButton');
Click ('OkButton');
第二个 Click
仅在模态表单关闭时执行,我必须手动执行此操作。
我不太了解模态表单在后台如何工作,但必须有某种方法来规避这种行为。天真地,我想以某种方式“在线程中”执行 ShowModal ,以便“主线程”保持响应。现在我知道在线程中运行 ShowModal
可能会弄乱一切。还有其他选择吗?有什么方法可以规避 ShowModal
的阻塞性质吗?有人在 Delphi 中进行过 GUI 测试吗?
我了解外部工具(来自 QA 或其他工具)并且我们使用这些工具,但这个问题是关于 IDE 中的 GUI 测试。
谢谢!
In this interesting blog post on delphiXtreme I read about DUnit's built-in GUI testing capabilities (basically an alternative test case class TGUITestCase
defined in unit GUITesting
that has several utility functions for invoking actions in the GUI). I was quite happy with it until I noticed that it didn't work with modal forms. For example the following sequence won't work if the first button shows a modal configuration form:
Click ('OpenConfigButton');
Click ('OkButton');
The second Click
is only executed when the modal form is closed, which I have to do manually.
I don't know much about how modal forms work in the background but there must be some way to circumvent this behaviour. Naively, I want to somehow execute the ShowModal
"in a thread" so that the "main thread" stay responsive. Now I know that running ShowModal
in a thread will probably mess up everything. Are there any alternatives? any way to circumvent the blocking nature of a ShowModal
? Has anybody some experiences with GUI testing in Delphi?
I know about external tools (from QA or others) and we use those tools, but this question is about GUI testing within the IDE.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法通过调用 ShowModal 来测试模态表单;因为正如您非常正确地发现的那样,这会导致您的测试用例代码在模态表单等待用户交互时“暂停”。
原因是
ShowModal
将您切换到“辅助消息循环”,直到表单关闭后才会退出。然而,模态形式仍然可以被测试。
Show
方法显示通常模态表单。Show
意味着表单不会通过设置模态结果来关闭。ModalResult
是否正确即可。警告
您可以使用此技术通过显式显示非模态形式来测试特定的模态形式。但是,任何显示模式形式的测试代码(例如错误对话框)都会暂停您的测试用例。
即使您的示例代码:
Click ('OpenConfigButton');
也会导致调用 ShowModal,并且无法以这种方式进行测试。要解决此问题,您需要将“显示命令”注入到您的应用程序中。如果您不熟悉依赖注入,我推荐您在 YouTube 上观看 Misko Hevery 的 Clean Code Talks 视频。然后在测试时,您注入“显示命令”的合适版本,该版本不会显示模式形式。
例如,如果单击“确定”按钮时验证失败,您的模态表单可能会显示错误对话框。
所以:
1)定义一个接口(或抽象基类)来显示错误消息。
2) 您正在测试的表单可以保存对接口的注入引用 (
FErrorMessage: IErrorMessage
),并在验证失败时使用它来显示错误。3) 用于生产代码/注入的 IErrorMessage 的默认版本将像往常一样简单地显示消息。
4) 测试代码将注入 IErrorMessage 的模拟版本,以防止测试被暂停。
5) 您的测试现在可以执行通常会显示错误消息的情况。
6) 您可以进一步使用模拟 IErrorMessage 来实际验证消息文本。
7)现在早期的测试变成:
You can't test modal forms by calling
ShowModal
; because as you have quite rightly discovered, that results in your test case code 'pausing' while the modal form awaits user interaction.The reason for this is that
ShowModal
switches you into a "secondary message loop" that does not exit until the form closes.However, modal forms can still be tested.
Show
method.Show
means the form won't be closed by setting the modal result.ModalResult
is correct.WARNING
You can use this technique to test a specific modal form by explicitly showing it non-modally. However, any code under test that shows a modal form (e.g. Error Dialog) will pause your test case.
Even your sample code:
Click ('OpenConfigButton');
results in ShowModal being called, and cannot be tested in that manner.To resolve this, you need your "show commands" to be injectible into your application. If you're unfamliar with dependency injection, I recommend Misko Hevery's Clean Code Talks videos available on You Tube. Then while testing, you inject a suitable version of your "show commands" that won't show a modal form.
For example, your modal form may show an error dialog if validation fails when the Ok button is clicked.
So:
1) Define an interface (or abstract base class) to display an error messages.
2) The form you're testing can hold an injected reference to the interface (
FErrorMessage: IErrorMessage
), and use it to show an error whenever validation fails.3) The default version of IErrorMessage used / injected for production code will simply display the message as usual.
4) Test code will inject a mock version of IErrorMessage to prevent your tests from being paused.
5) Your tests can now execute cases that would ordinarily display an error message.
6) You can take the mock IErrorMessage a step further to actually verify the message text.
7) Now the earlier test becomes:
其实Delphi中有一种测试模态窗口的方法。当显示模式窗口时,您的应用程序仍然处理窗口消息,因此您可以在显示模式窗口之前将消息发布到某些帮助程序窗口。然后,您的消息将从模态循环中处理,允许您在模态窗口仍然可见时执行代码。
最近我一直在开发一个简单的库来处理这个问题。您可以从这里下载代码:https://github.com/tomazy/DelphiUtils(请参阅:FutureWindows .pas)。
使用示例:
There is actually a way to test modal windows in Delphi. When a modal window is shown your application still processes windows messages so you could post a message to some helper window just before showing the modal window. Then your message would be handled from the modal loop allowing you to execute code while the modal window is still visible.
Recently I've been working on a simple library to handle this very problem. You can download the code from here: https://github.com/tomazy/DelphiUtils (see: FutureWindows.pas).
Sample usage: