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イベントのハンドラーで初期化と関連するすべての検証を実行することです。ホワイトが別のプロセスでテスト対象のアプリケーションを実行するという事実により、競合状態があると思います。

GetWindow初期化の失敗が検出される前に呼び出された場合、テストは成功します。失敗検出がレースに勝つと、アプリが閉じられるため、GetWindow失敗します。

White のドキュメントを調べたり、サンプルを閲覧したりしていますが、このシナリオの回避策が見つかりません。アプリのコードを変更することは、まだテスト ハーネスを持っていないため、最後の手段にする必要があります (それが私を行き詰まらせた理由です。私のアイデアはすべて、アプリの変更を中心に展開しています)。

4

2 に答える 2

1

を作成しますWaitHandle。オブジェクトをリセット
するイベントを追加します。 テストでは、が終了するまでスリープ状態になります。LoadedWaitHandle
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 に答える