Медленная итерация по элементам в WatiN - PullRequest
2 голосов
/ 13 мая 2011

Я пишу заявку с помощью Watin.Замечательно, но при выполнении анализа производительности в моей программе более 50% времени выполнения тратится на циклический просмотр списков элементов.

Например: foreach (TextField bT в browser.TextFields) {

Очень медленно.

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

Доступ к количеству элементовтакже кажется медленным, например;browser.CheckBoxes.Count

Спасибо за любые советы, Крис

Ответы [ 3 ]

6 голосов
/ 17 мая 2011

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

Более конкретныйваши селекторы, тем быстрее все пойдет.Избегайте использования «browser.Elements», так как это действительно универсально.Я не уверен, что это сильно экономит, но делать что-то вроде browser.Body.Elements выбрасывает элементы заголовка из области проверяемых вещей и может сохранить несколько вычислений.

Когда я говорю «охват», учтите, что WatiN всегда начинается со всего DOM.Можете ли вы придумать способы ограничить область действия элементов, возможно, текстовыми полями в главном элементе div на вашей странице?WatiN возвращает Elements и ElementCollections, каждый из которых может иметь свою собственную ElementCollection.Этот div, вероятно, имеет определенный идентификатор, поэтому вы можете сделать что-то вроде

var textFields = ie.Div("divId").TextFields;

Ищите возможности быть более конкретными, и вы можете использовать LINQ, чтобы описать то, что вы хотите более четко.Например, можете ли вы написать что-то вроде:

ie.Body.TextFields.
  Where(tf => !string.IsNullOrWhiteSpace(tf.ClassName) && tf.ClassName.Contains("classname")).ToList().
  Foreach(tf => tf.Value = "Your Text");

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

ie.Body.TextFields.ToList().
  Foreach(tf => {
    if(!string.IsNullOrWhiteSpace(tf.ClassName) && tf.ClassName.Contains("classname")) { 
      tf => tf.Value = "Your Text"
    }
  });

«Найти»Спецификаторы .By * "также помогают WatiN работать с нужными коллекциями быстрее и являются более элегантным сокращением для того, что я написал выше:

ie.Body.TextFields.Filter(Find.ByClass("class")).ToList().ForEach(tf => tf.Value = "Your Text");

И, как последний совет, это* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ”*” Не ”Это" не "" »”. "” ”" »» ”» »" »». "” »” "” »." * ”” ”.” ”” "” »." ””.

Надеюсь, это поможет.Я ищу способы ускорить свои собственные тесты.

0 голосов
/ 17 мая 2011

Спасибо Dahv за действительно подробный ответ.В моем случае я ускорил свои тесты примерно в 10 раз, используя ряд трюков, некоторые из которых похожи на ваши:

  • Уточнение области видимости как у вас, так и у Prostynick (в моем случае с использованием Form1.TextField и т. Д.)
  • Сначала проверьте, соответствует ли browser.html моему регулярному выражению, прежде чем проверять, соответствуют ли поля
  • Использование оболочки RegEx GehSoft.PRCE - сопоставление с собственным регулярным выражением собственного кода намного быстрее, чем .NET для небольшихстога.Поэтому, чтобы найти TextField, я бы сделал:

        Gehtsoft.PCRE.Regex regexString = new Gehtsoft.PCRE.Regex("[Nn]ame");
          foreach (TextField bT in browser.TextFields)
                        {
                            //Skip if no match
                            if (!regexString.Execute(bT.Name).Success) continue;
    
  • До того, как я зацикливался на списке регулярных выражений, затем внутри него я зацикливался на TextFields.Создание цикла TextFields в верхней петле улучшило скорость примерно в 3 раза.

0 голосов
/ 13 мая 2011

Если вам действительно нужно перебрать все текстовые поля, другого пути нет. Как отметил @Xaqron, это зависит от IE. Но, возможно, вам просто нужно перебирать текстовые поля, например,. указано <div/>? Сначала найти его, а затем выполнить итерацию по текстовым полям.

...