0

编辑:我选择了使用FlaUI的路线。我已经更新了这个问题的标签以包含它,并将我的解决方案作为答案发布。

我正在为监视某些 Windows 窗体应用程序以查看这些应用程序是否正在运行或崩溃的应用程序编写一些集成测试。

要求之一是确定它是否显示错误窗口或信息窗口并采取相应措施。

例如:

为了模拟显示信息窗口的情况,我创建了一个测试应用程序(如上所示),其中包含一个按钮,单击该按钮会显示一些信息窗口。

这就是我的测试的样子:

[Fact]
public async Task Can_Identify_An_Information_Window()
{
    //ARRANGE
    // My service that will start the app:
    await _myUIAutomationService.StartAppAsync("PathToMyTestApp");

    //Find the app window
    var appProcess = Process.GetProcessesByName("MyTestApp'sProcessName")[0];
    var appWindow = AutomationElement.FromHandle(appProcess.MainWindowHandle);

    //Find the buttons on the app window:
    var buttons = appWindow.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
    //Grab the button that will show the information window and click it to show the information window:
    foreach (AutomationElement button in buttons)
    {
        if (button.Current.Name == "Open Info Window")
        {
            // click it to open the information window:
            var invoke = (InvokePattern)button.GetCurrentPattern(InvokePattern.Pattern);
            invoke.Invoke();
        }
    }

    //ACT
    // My service that will get the status of the app including the windows it's showing:
    var appstatus = await _myUIAutomationService.GetAppStatusAsync("MyTestApp'sName");
    var informationWindow = appstatus.InformationWindows[0];

    //ASSERT
    Assert.NotNull(informationWindow);
}

invoke.Invoke();我对这个测试的问题是,在我手动单击显示的信息窗口上的“确定”之前,我无法越过这条线。

我什至尝试将事件处理程序附加到按钮来处理这个问题,但这并没有成功,因为我永远无法进入该OnInvoked处理程序方法:

Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent,
                                        button,
                                        TreeScope.Element,
                                        OnInvoked);

// Handler for information window showing button invoke event:
private void OnInvoked(object Sender, AutomationEventArgs E)
{
    // The control never reaches here.
}

我只需要这个测试是自动的,无需人工干预。

任何帮助/方向将不胜感激。

谢谢!

4

1 回答 1

1

我尝试了@stuartd 在评论中建议的方式,但不幸的是,这并没有解决,因为我遇到了同样的问题,即在该.Invoke()方法被调用时不会去任何地方(在进行手动干预之前调用)。

所以我研究了Roman Roemer的这个很棒的 nuget 包,叫做FlaUI ,之后事情变得非常顺利。

在此处输入图像描述

这就是我的测试现在的样子:

using FlaUI.UIA3;
using FlaUI.Core.AutomationElements;

[Fact]
public async Task Can_Identify_An_Information_Window_Async()
{
    //ARRANGE
    // My service that will start the app:
    await _myUIAutomationService.StartAppAsync("PathToMyTestApp");

    //Create FLA UI core application (i.e. myApp) from the Process object (i.e. appProcess).
    var appProcess = Process.GetProcessesByName("MyTestApp'sProcessName")[0];
    var myApp = new FlaUI.Core.Application(appProcess);

    using (var automation = new UIA3Automation())
    {
        var window = myApp.GetMainWindow(automation);
        window.WaitUntilClickable(TimeSpan.FromSeconds(2)); //Wait with a timeout duration of 2 seconds.

        //Find the button
        var myBtn = window.FindFirstDescendant(cf => cf.ByText("Open Info Window"));
        myBtn.Click(true); // This will show the information window. The true flag show the mouse pointer actually finding the button and clicking it. It's very COOL!

        //ACT
        //Get the status
        var appstatus = await _myUIAutomationService.GetAppStatusAsync("MyTestApp'sName");
        var informationWindow = appstatus.InformationWindows[0];

        //ASSERT
        Assert.NotNull(informationWindow);
    }
}
于 2021-08-10T13:54:24.963 回答