我使用Project White为我的应用程序编写了一个简单的UI自动化测试。它只是启动应用程序并检查主窗口是否存在。这是在NUnit测试的上下文中完成的:
///AppTest.cs
[Test]
public void ShouldDisplayMainForm() {
using( var wrapper = new WhiteWrapper( MYAPP_PATH ) ){
Window win = wrapper.GetWindow( "MYAPP_MAIN_FORM_TITLE" );
Assert.IsNotNull(win);
}
}
///WhiteWrapper.cs
using System;
using White.Core;
using White.Core.Factory;
using White.Core.UIItems;
using White.Core.UIItems.WindowItems;
namespace MGClient.Test {
internal class WhiteWrapper : IDisposable {
private readonly Application mHost;
private readonly Window mMainWindow;
public WhiteWrapper( string pPath ) {
mHost = Application.Launch( pPath );
}
public WhiteWrapper( string pPath, string pMainWindowTitle )
: this( pPath ) {
mMainWindow = GetWindow( pMainWindowTitle );
}
public void Dispose() {
if( mHost != null )
mHost.Kill();
}
public Window GetWindow( string pTitle ) {
return mHost.GetWindow( pTitle, InitializeOption.NoCache );
}
public TControl GetControl<TControl>( string pControlName ) where TControl : UIItem {
return mMainWindow.Get<TControl>( pControlName );
}
}
}
问题是测试结果是随机的:有时它会失败,有时它会成功,而不会遵循模式。
设置测试环境以便初始化失败:我希望看到测试失败。问题是我的应用程序的主窗体在其Load
事件的处理程序中执行其初始化和所有相关验证。我认为存在竞争条件,因为怀特在一个单独的过程中运行被测试的应用程序:
在检测到初始化失败之前调用GetWindow
时,测试成功。当故障检测赢得比赛时,它会关闭应用程序,因此这会使GetWindow
失败。
我正在查看White文档并浏览示例,但我无法找到此方案的解决方法。更改应用程序的代码应该是最后的手段,因为我还没有测试工具(这就是让我陷入困境的原因:我所有的想法都围绕着改变应用程序)。
答案 0 :(得分:1)
创建WaitHandle
。
将事件添加到Loaded
,这将重置WaitHandle
对象
在您的测试中使用WaitHandle.WaitOne()
,这将使其在Load
完成之前进入休眠状态。
[Test]
public void ShouldDisplayMainForm() {
using( var wrapper = new WhiteWrapper( MYAPP_PATH ) ){
WaitHandle handle = new ManualResetEvent(false);
Window win = wrapper.GetWindow( "MYAPP_MAIN_FORM_TITLE" );
win.Loaded += (sender, e) => handle.set(); //Loaded or Onload, depending on framework
handle.WaitOne();
Assert.IsNotNull(win);
}
}
这有一个小问题,如果已经调用了Loaded
,你将无限期地等待。
您可以查看IsHandleCreated
,它会告诉您加载是否完成。
这是一个可行的蹩脚解决方案。
[Test]
public void ShouldDisplayMainForm() {
using( var wrapper = new WhiteWrapper( MYAPP_PATH ) ){
Window win = wrapper.GetWindow( "MYAPP_MAIN_FORM_TITLE" );
While (win.IsHandleCreated)
Thread.Sleep(1000);
Assert.IsNotNull(win);
}
}
答案 1 :(得分:1)
我查看了White.Core.UIItems.WindowItems.Window
的公共界面,发现与WaitTill
属性配对的IsCurrentlyActive
方法可以解决问题:
///AppTest.cs
[Test]
public void ShouldDisplayMainForm() {
using( var wrapper = new WhiteWrapper( MYAPP_PATH ) ){
Window win = wrapper.GetWindow( "MYAPP_MAIN_FORM_TITLE" );
Assert.IsNotNull(win);
win.WaitTill( ()=> win.IsCurrentlyActive );
}
}
现在测试总是失败。有时它会在GetWindow
调用中超时,有时会在WaitTill
中执行。但是在初始化时总是会失败,所以这对我来说已经足够了。
对于其他白色新手:文档非常稀缺,所以请耐心看看来源(如果你找到一些好的文档来源,请告诉我们)。