单元测试 WPF 控件获取对子对话框的访问权限

Unit Test WPF Control Get Access to Child Dialog

我们正在使用 NUnit 测试 WPF 控件。 文本夹具基本上打开一个测试 window,其中包含要在新线程上测试的控件。然后使用Microsoft UI Automation (UIA) 与控件进行交互。

新线程显示 window 并启动调度程序。事情按预期工作。

我们 运行 遇到的问题是此控件可以启动对话框。对话框启动后,我们需要与其进行交互并关闭它。我无法获得对此对话框的引用来完成此任务。

一个不起作用的解决方案是使用 Application.Current.Windows 获取所有 windows 然后遍历它们直到找到对话框。这不起作用,因为在单元测试期间 Application.Current = null。现在,如果我们只关心这个测试,我们可以实例化一个应用程序。但是,这会干扰其他测试,因为当我们的 Application 变量超出范围(在测试结束时)时,Application 将自动进入关闭模式。结果,其他测试将失败(最明显的是因为 InitializeComponent 通常调用 System.Windows.Application.LoadComponent,而在关闭模式下无法调用)。

我想我们需要的是 Application.Current.Windows 的替代方案。

我找到了解决问题的有效方法。

UIA 触发了一些事件。其中一个表示新 window 已打开。

订阅 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 );
        }
    }
}

在处理程序中,您没有对已打开的 window 的引用。但是,您可以从 Win32 句柄中获取它。

我遇到的另一个问题是测试将在 Window 打开时继续进行。一些测试可能依赖于 window。为了解决这个问题,我造成了延迟,直到 Window 准备好。

while (MyWindow == null)
{
    System.Threading.Thread.Sleep(10);
}