1

NUnit を使用して WPF コントロールをテストしています。テキスト フィクスチャは基本的に、新しいスレッドでテストするコントロールを含むテスト ウィンドウを開きます。次に、Microsoft UI オートメーション (UIA) を使用してコントロールを操作します。

新しいスレッドがウィンドウを表示し、ディスパッチャーを開始します。物事は期待どおりに機能します。

私たちが直面している問題は、このコントロールがダイアログを起動できることです。ダイアログが起動したら、対話して閉じる必要があります。このタスクを実行するためのこのダイアログへの参照を取得できませんでした。

うまくいかない解決策の 1 つは、Application.Current.Windows を使用してすべてのウィンドウを取得し、ダイアログが見つかるまで繰り返し処理することです。単体テスト中に Application.Current = null であるため、これは機能しません。このテストだけを気にする場合は、アプリケーションをインスタンス化するだけです。ただし、アプリケーション変数が範囲外になると (テストの最後に)、アプリケーションは自動的にシャットダウン モードになるため、これは他のテストに干渉します。その結果、他のテストは失敗します (最も顕著なのは、InitializeComponent が通常、シャットダウン モード中に呼び出すことができない System.Windows.Application.LoadComponent を呼び出すためです)。

必要なのは、Application.Current.Windows に代わるものだと思います。

4

1 に答える 1

1

私の問題に対する実用的な解決策を見つけました。

UIA は多くのイベントを発生させます。それらの 1 つは、新しいウィンドウが開いたことを示します。

ハンドラーを WindowOpenedEvent にサブスクライブします。

Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Children, new AutomationEventHandler(NewWindowHandler));

public void NewWindowHandler(Object sender, AutomationEventArgs e)
{
    AutomationElement element = (AutomationElement)sender;
    if (element.Current.Name == "PUT YOUR NAME HERE") 
    {
        HwndSource hSource = HwndSource.FromHwnd(new IntPtr(element.Current.NativeWindowHandle));
        MyWindow = hSource.RootVisual as WavefrontToolkit.FormulaEditor.FormulaEditor;
        Assert.IsNotNull(_MyWindow );
        }
    }
}

ハンドラーには、開かれたウィンドウへの参照がありません。ただし、Win32 ハンドルから取得できます。

私が遭遇した他の問題は、ウィンドウが開いているときにテストが続行されることです。テストの一部は、そのウィンドウに依存している可能性があります。それに対処するために、ウィンドウの準備が整うまで遅延を引き起こします。

while (MyWindow == null)
{
    System.Threading.Thread.Sleep(10);
}
于 2015-04-27T20:32:10.840 に答える