您不能通过调用
ShowModal
来测试模态表单,因为正如您已经正确发现的那样,这会导致您的测试案例代码“暂停”,而模态表单等待用户交互。
原因是
ShowModal
会将您切换到一个“辅助消息循环”,该消息循环直到表单关闭才退出。
然而,模态表单仍然可以被测试。
1. 使用
普通的Show
方法显示
通常是模态的表单。
2. 这允许您的测试案例代码继续运行,并模拟用户操作。
3. 可以像平常一样测试这些操作和效果。
4. 您还需要一个特别针对模态表单的额外测试:
a. 模态表单通常是通过设置模态结果来关闭的。
b. 使用
Show
意味着不会通过设置模态结果来关闭表单。
c. 如果现在模拟单击“确定”按钮...
d. 您只需检查
ModalResult
是否正确即可。
警告:
您可以使用此技术通过显式非模态方式显示特定的模态表单进行测试。但是,任何正在测试中的代码如果显示模态表单(例如错误对话框),都将暂停您的测试案例。
即使您的示例代码:
Click ('OpenConfigButton');
也会导致调用ShowModal,并且不能以这种方式进行测试。
为了解决这个问题,您需要使“显示命令”可注入到您的应用程序中。如果您不熟悉依赖项注入,我建议您在YouTube上查看Misko Hevery的《干净代码演讲》视频。然后在测试期间,您注入一个适当的版本的“显示命令”,该版本不会显示模态表单。
例如,如果单击“确定”按钮时验证失败,则模态表单可能会显示错误对话框。
因此:
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;
end;
3) 生产代码使用的IErrorMessage默认版本将像往常一样显示消息。
4) 测试代码将注入模拟版本的IErrorMessage,以防止测试被暂停。
5) 您的测试现在可以执行通常会显示错误消息的用例。
procedure TTestClass.TestValidationOfBlankEdit;
begin
Form1.Show;
Click('OkButton');
CheckEquals(0, Form1.ModalResult);
end;
6) 您可以进一步使用模拟的 IErrorMessage 来验证消息文本。
TMockErrorMessage = class(TInterfaceObject, IErrorMessage)
private
FLastErrorMsg: String;
protected
procedure ShowError(AMsg: String);
public
property LastErrorMsg: String read FLastErrorMsg;
end;
TTestClass = class(TGUITesting)
private
FMockErrorMessage: TMockErrorMessage;
...
end;
procedure TTestClass.SetUp;
begin
FMockErrorMessage := TMockErrorMessage.Create;
end;
7) 现在之前的测试变成了:
procedure TTestClass.TestValidationOfBlankEdit;
begin
Form1.Show;
Click('OkButton');
CheckEquals(0, Form1.ModalResult);
CheckEqulsString('Please fill in your name', FMockErrorMessage.LastErrorMsg);
end;
ShowModal
代码。那是不可行的。你需要做的是在调用ShowModal
之前向你的窗体发送一条消息。当窗体处理该消息时,它可以调用测试代码,进而点击按钮等操作。 - David Heffernan