【问题标题】:UI Automation - InvokePattern.Invoke() blocking execution until user interaction in integration testsUI 自动化 - InvokePattern.Invoke() 阻止执行,直到集成测试中的用户交互
【发布时间】:2021-10-13 05:10:09
【问题描述】:

编辑:我选择了使用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.
}

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

任何帮助/指导将不胜感激。

谢谢!

【问题讨论】:

标签: c# integration-testing ui-automation ui-testing flaui


【解决方案1】:

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

因此,我研究了 Roman Roemer 编写的名为 FlaUI 的超棒 nuget 包,之后事情进展顺利。

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

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

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2017-10-22
    • 2021-02-22
    相关资源
    最近更新 更多