Перейти к содержимому

Фотография

Покритикуйте код поиска объекта, пожалуйста


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 4

#1 Stanislav_alphaopen

Stanislav_alphaopen

    Новый участник

  • Members
  • Pip
  • 68 сообщений
  • ФИО:Васенков Станислав
  • Город:Москва

Отправлено 08 мая 2015 - 09:25

Прошу покритиковать код поиска объекта. Особенно не уверен в findEngineReserv

У меня desctop Java-приложение на платформе NetBeans(swing, динамическое дерево объектов).

////////////////////////////////////////////////////////////////
//Общая функция поиска объектов, резервная функция поиска объекта, конструктор поиска объекта и функция поиска конкретных объектов
///////////////////////////////////////////////////////////////
//findEngine - ищет конкретный объект по заданным variable и property с указанной глубиной depth в указанном объекте mainObj
//findEngineReserv - если findEngine не находит объект, данная функция пытается найти его другими способами
//findConstructor - если искомый объект нужно найти в объекте, отличном от корневого, эта функция находит находит второй и передает его в findEngine
//findObj(название объекта) - поиск конкретных объектов, основная функция, которая вызывается в других скриптах. В switch/case указаны свойства и значения для поиска объектов.


//Поиск объектра
function findEngine(variable, property, depth, mainObj)
{
      depth = depth == null?50:depth;
      var result = mainObj.FindAllChildren(variable, property, depth);
      result = (new VBArray(result)).toArray(); //здесь периодически появляется ошибка и ругается на VBArray
      if (result.length > 1)  {
            Log.Warning("Надено более 1 объекта методом FindAllChildren. По умолчанию выбран первый объект. Необходимо уточнить поиск в findObj. Найдено объектов: " + result.length);
      }
    return result.length == 0?findEngineReserv(variable, property, depth, mainObj):result[0];
}


//Резервный поиск объектра
function findEngineReserv(variable, property, depth, mainObj)
{
      Log.Message("Работает резервный поиск объектов");              
      if (!mainObj.Exists) {
            return  Log.Error("Объект MainObj не найден");
      }
        
      var time = 5;  
      var temp = 0;
      while (temp < time) {      
            Log.Message ("Этап резервного поиска объекта : " + temp);
            Delay(100);
            var resultObj = mainObj.FindChild(variable, property, 30);
            if (resultObj.Exists) {
                  return resultObj;
            }
            temp++;
      }    

      var temp1 = 0;
      while (temp1 < 300) {
            Log.Message ("Этап резервного поиска объекта с Refresh(): " + temp1);    
            Delay(100);
            resultObj.Refresh();
            if (resultObj.Exists) {
                  return resultObj;
            }
            temp1 += 100;
      }
      
    Log.Warning("Объект найден с затруднениями", "Variables: " + variable.toString() + "\nProperty: " + property.toString());
    return resultObj;
  }  


//Конструктор поиска объекта, 
function findConstructor(variable, property, depth, variableMain, propertyMain, depthMain)
{
    if (variableMain&&propertyMain)  { 
              var mainObj = findEngine(variableMain, propertyMain, depthMain);          
      } else {
              var mainObj = Sys.WaitProcess("javaw", 20000);
    }
    return findEngine(variable, property, depth, mainObj);
}

    
//Поиск конкретных объектов
function findObj(searchObj) {
      var variable, property, depth, variableMain, propertyMain, depthMain;

      switch(searchObj) {

            //Возвращает object Всплывающего окна
            case "BasicComboPopup":
                  var variable = ["JavaClassName", "VisibleOnScreen"];
                  var property = ["BasicComboPopup$1", true]; 
                   var depth = 18;
            break;   

            //Возвращает object Конфигурации 
            case "Configuration":
                  var variable = ["JavaClassName", "VisibleOnScreen"];
                  var property = ["TreeView$ExplorerTree", true];
                  var depth = 9;
                  
                  var variableMain = ["JavaClassName", "VisibleOnScreen", "AWTComponentAccessibleName"];
                  var propertyMain = ["ProjectManagerTopComponent", true, "Проект"];
                  var depthMain = 18;
            break;     

      }
      return findConstructor(variable, property, depth, variableMain, propertyMain, depthMain);      
}

  • 0

#2 Genka

Genka

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 328 сообщений
  • ФИО:Геннадий Алпаев
  • Город:Украина, Днепр


Отправлено 08 мая 2015 - 10:01

return result.length == 0?findEngineReserv(variable, property, depth, mainObj):result[0];

 

Я бы заменил тернарный оператор на обычный if, читаться будет проще

 

if (!mainObj.Exists) {
            return  Log.Error("Объект MainObj не найден");
      }

 

Log.Error ничего не возвращает, так что у вас всегда будет возвращаться null.

Ну и вообще, проверка существования объектов делается либо неявно (при обращении к объекту), либо явно (с помощью методов Wait).

В данном случае, если объект не существует, вы получите в лог дополнительное сообщение об ошибке. Короче, это просто лишний блок, на мой взгляд.

 

function findEngineReserv(variable, property, depth, mainObj)

 

Для параметра depth не предусмотрено значение по умолчанию

 

switch(searchObj)

 

 

Не хватает секции default

 

var temp = 0;

 

Не стоит так переменные называть (temp, temp1)

Кроме того, переменная temp1 там явно лишняя, можно было заново использовать temp.

 

//здесь периодически появляется ошибка и ругается на VBArray

 

 

Точно не скажу, но есть подозрение, что это происходит в том случае, когда ничего не найдено (т.е. массив пустой), попробуйте обернуть в try...catch и отловить ошибку

 

var variable = ["JavaClassName", "VisibleOnScreen"];
var property = ["BasicComboPopup$1", true];

 

Вы перепутали. Первый массив - это свойства (properties), а второй - их значения (values). Вам, может, понятно, но для кого-то другого будет путаница.


  • 0

TestComplete для начинающих (видеозаписи курса)

Software Testing Automation Tips (50 вещей, которые должен знать каждый автоматизатор, книга на английском языке)

Онлайн-учебник "Автоматизация тестирования от «А» до «Ы»"
Сборник рецептов по TestComplete (книга на английском языке)
Онлайн-учебник по TestComplete
Онлайн-учебник по SilkTest


#3 Stanislav_alphaopen

Stanislav_alphaopen

    Новый участник

  • Members
  • Pip
  • 68 сообщений
  • ФИО:Васенков Станислав
  • Город:Москва

Отправлено 08 мая 2015 - 12:17

Геннадий, спасибо!

 

 

if (!mainObj.Exists) {
            return  Log.Error("Объект MainObj не найден");
      }

 

Log.Error ничего не возвращает, так что у вас всегда будет возвращаться null.

Ну и вообще, проверка существования объектов делается либо неявно (при обращении к объекту), либо явно (с помощью методов Wait).

В данном случае, если объект не существует, вы получите в лог дополнительное сообщение об ошибке. Короче, это просто лишний блок, на мой взгляд.

Меня как раз устраивает, что будет выводится ошибка, ибо если mainObj не найден, дальше просто нет смысла идти.

проверка существования объектов делается либо неявно (при обращении к объекту) - можете пояснить?

 

 

Остальное поправил, спасибо!


  • 0

#4 Genka

Genka

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 328 сообщений
  • ФИО:Геннадий Алпаев
  • Город:Украина, Днепр


Отправлено 08 мая 2015 - 12:56

 

проверка существования объектов делается либо неявно (при обращении к объекту) - можете пояснить?

 

Почитайте вот тут первый вопрос и ссылку на главу 3.5 в этом вопросе (про методы Wait...). Если все еще не будет понятно - отпишитесь тут, я объясню.


  • 0

TestComplete для начинающих (видеозаписи курса)

Software Testing Automation Tips (50 вещей, которые должен знать каждый автоматизатор, книга на английском языке)

Онлайн-учебник "Автоматизация тестирования от «А» до «Ы»"
Сборник рецептов по TestComplete (книга на английском языке)
Онлайн-учебник по TestComplete
Онлайн-учебник по SilkTest


#5 XXX

XXX

    Опытный участник

  • Members
  • PipPipPipPip
  • 284 сообщений
  • ФИО:Денис Викторович
  • Город:Санкт-Петербург


Отправлено 08 мая 2015 - 21:42



function findEngine(variable, property, depth, mainObj)

Проверяется depth на null, было бы здорово и mainObj ..да и поменял бы местами с depth



var result = mainObj.FindAllChildren(variable, property, depth);
      result = (new VBArray(result)).toArray(); //здесь периодически появляется ошибка и ругается на VBArray
      if (result.length > 1)  {
            Log.Warning("Надено более 1 объекта методом FindAllChildren. По умолчанию выбран первый объект. Необходимо уточнить поиск в findObj. Найдено объектов: " + result.length);
      }
    return result.length == 0?findEngineReserv(variable, property, depth, mainObj):result[0];

я бы заменил на что-то более простое 



return mainObj.Find([property, "Visible"], [value, "True"], depth);

да и скорее бы переименовал метод в getObj =)

 

Метод findEngineReserv переименовал бы в WaitObj и применял бы отдельно там, где нужно действительно ожидать, а не каждый раз, когда объект не существует. Два цикла while можно смело объеденить в один вставив перед if свой Refresh()..задача же стоит определить объект и работать с ним далее, а не узнать на каком "этапе резервного поиска" он определяется с помощью TC. К тому же если он у тебя находится, то отрабатывает return объекта внутри цикла, поэтому Log.Warning("Объект найден с затруднениями") нужно заменить на Log.Error("Искомый объект не найден..")

 

В методе findObj(searchObj) заместо свойства VisibleOnScreen использовал бы Visible, иначе могут быть проблемы при работе с несколькими приложениями (например, программа + веб). Одна программа перекрывает другую, со св-вом VisibleOnScreen объект второй не найдется, в отличие от Visible


  • 0


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных