单元测试 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);
}
我们正在使用 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);
}