CodedUI: Почему поиск ячейки такой медленный? - PullRequest
5 голосов
/ 31 января 2012

У меня есть сетка (FlexGrid, от ComponentOne) в приложении Winform, и я пытаюсь найти ячейку в этой сетке, учитывая индекс столбца ячейки и ее значение.

У меня естьЯ написал метод расширения ниже, чтобы пройти по сетке и найти эту ячейку.

Я тестирую этот метод на сетке, которая имеет 6 столбцов и 64 строки.Мой код занял 10 минут, чтобы найти правильную ячейку (которая была в последней строке)

Можно ли как-нибудь ускорить мой алгоритм?

Примечание: я также пыталсяустановка PlayBack.PlayBackSetting.SmartMatchOption в TopLevelWindow, но, похоже, он ничего не меняет ...

Спасибо!

    public static WinCell FindCellByColumnAndValue(this WinTable table, int colIndex, string strCellValue)
    {

        int count = table.GetChildren().Count;
        for (int rowIndex = 0; rowIndex < count; rowIndex++)
        {
            WinRow row = new WinRow(table);
            WinCell cell = new WinCell(row);
            row.SearchProperties.Add(WinRow.PropertyNames.RowIndex, rowIndex.ToString());
            cell.SearchProperties.Add(WinCell.PropertyNames.ColumnIndex, colIndex.ToString());

            cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);
            if (cell.Exists)
                return cell;
        }

        return new WinCell();
    }

Редактировать

Я изменил свой метод так, как показано ниже (например, я больше не использую winrow), кажется, это примерно в 3 раза быстрее.Для поиска ячейки в таблице с 3 строками и 6 столбцами по-прежнему требуется 7 секунд, поэтому она все еще довольно медленная ...

Я отмечу этот ответ как принятый позже, чтобы оставить время другим людям.предложить что-то лучшее

    public static WinCell FindCellByColumnAndValue(this WinTable table, int colIndex, string strCellValue, bool searchHeader = false)
    {
        Playback.PlaybackSettings.SmartMatchOptions = Microsoft.VisualStudio.TestTools.UITest.Extension.SmartMatchOptions.None;   
        int count = table.GetChildren().Count;
        for (int rowIndex = 0; rowIndex < count; rowIndex++)
        {
            WinCell cell = new WinCell(table);

            cell.SearchProperties.Add(WinRow.PropertyNames.RowIndex, rowIndex.ToString());
            cell.SearchProperties.Add(WinCell.PropertyNames.ColumnIndex, colIndex.ToString());


            cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);
            if (cell.Exists)
                return cell;
        }

        return new WinCell();
    }

Edit # 2: Я пытался использовать FindMatchingControls согласно предложению @ Andrii, и я почти на месте, за исключением того, что в коде ниже ячейкиИндекс столбца (c.ColumnIndex) имеет неправильное значение ..

    public static WinCell FindCellByColumnAndValue2(this WinTable table, int colIndex, string strCellValue, bool searchHeader = false)
    {

        WinRow row = new WinRow(table);
        //Filter rows containing the wanted value
        row.SearchProperties.Add(new PropertyExpression(WinRow.PropertyNames.Value, strCellValue, PropertyExpressionOperator.Contains));
        var rows = row.FindMatchingControls();
        foreach (var r in rows)
        {
            WinCell cell = new WinCell(r);
            cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);
            //Filter cells with the wanted value in the current row
            var controls = cell.FindMatchingControls();
            foreach (var ctl in controls)
            {
                var c = ctl as WinCell;
                if (c.ColumnIndex == colIndex)//ERROR: The only cell in my table with the correct value returns a column index of 2, instead of 0 (being in the first cell)
                    return c;
            }
        }
        return new WinCell();
    }

1 Ответ

6 голосов
/ 31 января 2012

Я бы предложил выполнить прямую петлю через дочерние элементы управления - согласно моему опыту, поиск элементов управления со сложным поиском crieteria в закодированном пользовательском интерфейсе часто работает медленно.

Редактировать:

Для повышения производительности лучше убрать подсчет дочерних таблиц и циклический просмотр строк.Также, чтобы избежать исключений при поиске элемента управления без номера строки, вы можете использовать метод FindMatchingControls , как показано ниже:

    public static WinCell FindCellByColumnAndValue(this WinTable table, int colIndex, string strCellValue, bool searchHeader = false)
    {
        Playback.PlaybackSettings.SmartMatchOptions = Microsoft.VisualStudio.TestTools.UITest.Extension.SmartMatchOptions.None;

        WinCell cell = new WinCell(table);
        cell.SearchProperties.Add(WinCell.PropertyNames.ColumnIndex, colIndex.ToString());
        cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);

        UITestControlCollection foundControls = cell.FindMatchingControls();
        if (foundControls.Count > 0)
        {
            cell = foundControls.List[0];
        }
        else
        {
            cell = null;
        }

        return cell;
    }

Когда поле таблицы будет найдено непосредственно в таблице, это сэкономит время дляПодсчет дочерних элементов управления в таблице.Кроме того, поиск без цикла for сэкономит время на поиск поля для каждой итерации номера строки, который не совпадает.

Поскольку номер строки повторяется по всем доступным значениям в вашем расширении - это не является существенным критерием поискав долгосрочной перспективе.В то же время каждая итерация по значению номера строки вызывает дополнительный контрольный запрос поиска - в итоге время выполнения метода умножается на количество строк в сетке.

...