1

我使用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事件的处理程序中执行其初始化和所有相关验证。我认为存在竞争条件,因为 White 在单独的进程中运行被测应用程序:

GetWindow检测到初始化失败之前调用时,测试成功。当故障检测赢得比赛时,它会关闭应用程序,因此这会GetWindow导致失败。

我正在查看 White 文档并浏览示例,但我找不到这种情况的解决方法。更改应用程序的代码应该是最后的手段,因为我还没有测试工具(这就是让我陷入困境的原因:我所有的想法都围绕着更改应用程序)。

4

2 回答 2

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);
   }
}
于 2013-06-05T18:21:49.910 回答
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. 但是初始化时它总是失败,所以这对我来说已经足够了。

对于其他白人新手:文档非常稀缺,所以请耐心等待并查看源代码(如果您找到一些好的文档源,请告诉)。

于 2013-06-05T19:46:53.487 回答