Операции меню TestStack.White, на которые влияет состояние занятости системы

Это автоматическое тестирование пользовательского интерфейса Windows 10 через nunit3.ConsoleRunner.

Это действительно довольно странно, но тот же код, который работал безупречно до моего отпуска, теперь зависает до 2 часов и более. Я создал свой собственный метод MenuClick() для наших тестов, потому что стандартный метод MenuBar.MenuItem() также часто зависал при переходе между пунктами меню 2-го уровня. Мой метод отлично работал до моего отпуска, как я уже сказал.

Во всяком случае, теперь вызов Menu.SubMenu() часто занимает 2 часа или больше, что неприемлемо.

Еще одна странность заключается в том, что тестовый код щелкает пункты меню 3-го уровня парами, где они оба открывают диалоговое окно «Обзор папок». Первый для выбора исходной папки, а другой для выбора папки назначения. «Зависание» происходит ТОЛЬКО (пока) при попытке получить 2-й уровень submenu для второго из пары кликов по пункту меню 3-го уровня.

Чтобы обойти это в настоящее время, я создаю новый поток, который вызывает menu = menuBar.MenuItem(). В основном потоке я жду, пока меню станет ненулевым или истечет время ожидания, прежде чем продолжить 500-мс спящий режим между проверками. По крайней мере, это позволяет мне повторить попытку. Однако оказывается, что при возникновении этого условия остальные операции меню во всем тестируемом приложении зависают, поэтому я не могу повторить попытку. Похоже на ошибку в области обработки меню 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;
}

person Jeff H    schedule 07.01.2019    source источник
comment
Вы действительно хотите установить menu = menu.SubMenu(...). Или вы хотите что-то вроде var item = menu.SubMenu(…); … элемент.Нажмите();   -  person StefanG    schedule 07.01.2019
comment
Привет, СтефанГ. Да, с точки зрения лучших практик я должен использовать var. Но это не изменит мою проблему, не так ли? может я что-то упускаю?   -  person Jeff H    schedule 08.01.2019
comment
Я имею в виду, что вы устанавливаете результат SubMenu в новую переменную. Не знаю деталей реализации SubMenu(), но это может быть проблемой.   -  person StefanG    schedule 08.01.2019
comment
SubMenu() возвращает объект Menu, поэтому я получаю результат объекта Menu и вызываю для него метод Click(). В любом случае, он возвращается практически сразу БОЛЬШИНСТВО времени, но когда это не так, для возврата требуется до 2 часов.   -  person Jeff H    schedule 09.01.2019


Ответы (1)


Хорошо, я определил, что операции меню 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");
        }
    }
}
person Jeff H    schedule 09.01.2019