受系统繁忙状态影响的TestStack.White菜单操作

时间:2019-01-07 15:07:20

标签: c# nunit-3.0 nunit-console teststack

这是通过nunit3.ConsoleRunner进行的Windows 10 UI自动化测试。

这真的很奇怪,但是在我休假之前可以完美工作的相同代码现在最多可以挂起2个小时或更长时间。我创建了自己的测试方法MenuClick(),因为在浏览第二级菜单项时,标准MenuBar.MenuItem()方法也经常挂起。正如我所说,我的方法在休假前效果很好。

无论如何,Menu.SubMenu()呼叫现在通常需要2个小时或更长时间才能完成,这是不可接受的。

另一个奇怪的地方是,测试代码成对地单击了第三级菜单项,它们都在其中打开“浏览文件夹”对话框。第一个选择源文件夹,另一个选择目标文件夹。尝试在一对三级菜单项中的第二次单击中获得第二级submenu时,“挂起”仅发生(到目前为止)。

要解决此问题,我正在生成一个新的线程,该线程调用menu = menuBar.MenuItem()。在主线程中,我等待菜单为非空或等待超时发生,然后在两次检查之间进行500 ms的睡眠。至少可以让我重试。但是,看来出现这种情况时,整个被测应用程序中的其余菜单操作都被挂起,因此我无法重试。似乎是TestStack.White菜单处理区域中的错误。

    public static void GetSubMenu(object obj)
{
    string[] menuNames = obj as string[];
    menu = menuBar.MenuItem(menuNames);
}

private static MenuBar menuBar = null;
private static Menu menu = null;

public static int ClickMenu(MenuBar mainMenu, params string[] menuItems)
{
    menuBar = mainMenu;
    bool bDone = false;
    menu = null;

    System.Threading.Thread t = new System.Threading.Thread(GetSubMenu);
    t.Start(menuItems);
    System.Threading.Thread.Sleep(500);

    DateTime timeOut = DateTime.Now + TimeSpan.FromSeconds(10);

    while (menu == null && DateTime.Now < timeOut)
    {
        System.Threading.Thread.Sleep(500);
    }

    if (menu != null)
    {
        menu.Click();
        bDone = true;
        log.Info($"ClickMenu success");
    }

    t.Abort();

    return bDone ? 1 : 2;
}

1 个答案:

答案 0 :(得分:0)

好的,我确定TestStack.White菜单操作容易受到系统繁忙状态的影响,在该状态下,试图执行操作的线程没有足够的时间片来工作,因此可能需要非常长的时间,很长一段时间。

将工作线程优先级设置为ThreadPriority.Highest是实现测试套件ClickMenu()方法的关键,如下所示:

public static class Util
{
    static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    private static MenuBar menuBar = null;

    public static void MenuItem(object obj)
    {
        string[] path = obj as string[];

        menuBar.MenuItem(path).Click();
    }

    public static void ClickMenu(MenuBar mainMenu, params string[] menuItems)
    {
        menuBar = mainMenu;

        System.Threading.Thread t = new System.Threading.Thread(MenuItem);
        t.Priority = System.Threading.ThreadPriority.Highest;
        t.Start(menuItems);

        DateTime startTime = DateTime.Now;

        while (t.IsAlive)
        {
            System.Threading.Thread.Sleep(100);
        }

        DateTime endTime = DateTime.Now;
        TimeSpan duration = endTime - startTime;

        if (duration.Seconds > 60)
        {
            log.Info($"Menu Operation duration = {duration.Seconds} sec");
        }
    }
}