11.8. Перехват событий

Назад: 11.7 Использование низкоуровневых процедур Содержание Дальше: 11.9 Ассоциации объектов (object mapping)

Событие (Event) в TestComplete – это действие, происходящее во время работы скриптов. Каждый раз, когда стартует и завершается работа скриптов, когда в лог отправляется сообщение (ошибка, предупреждение и т.п.), когда отправляется запрос нагрузочного теста и когда получен ответ, – во всех этих и в других случаях срабатывают события TestComplete.

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

Приведем 2 примера.

Первый. Предположим, что в процессе работы с тестируемым приложением произошло отсоединение от базы данных и в приложении выскочило сообщение, предупреждающее об этом. TestComplete в этом случае выдаст сообщение об ошибке “Unexpected window”, и попытается закрыть окно одним из предопределенных способов (нажатие кнопки OK, нажатие клавиши Esc и т.п.). Даже если ему удастся закрыть окно, проблему с отключением базы данных это не решит, поэтому было бы неплохо отловить подобную ситуацию и перед закрытием окна восстановить подключение к базе. Это возможно сделать с помощью события OnUnexpectedWindow.

Второй. Это реальная ситуация, время от времени возникающая в TestComplete. При работе с некоторыми нестандартными элементами управления (в частности с элементами управления Infragistics), иногда TestComplete генерировал ошибку “Improper command”. Это случалось потому, что при обработке действий пользователя эти контролы, как кажется TestComplete-у, перестают отвечать на запросы, хотя на самом деле они прекрасно работают. В результате после прогона скриптов мы имеем десяток ошибок “Improper command”, хотя все скрипты отработали правильно. Для решения подобной проблемы мы можем перехватывать событие OnLogError и проверять текст ошибки. Если это наш “Improper command” – то мы попросту игнорируем такую ошибку, в противном случае ошибка заносится в лог как обычно.

В качестве примера перехвата события OnEnexpectedWindow рассмотрим пример с Калькулятором. Мы откроем окно About Calculator, а затем попытаемся работать с главным окном Калькулятора, что вызовет ошибку Unexpected window. В обработчике этой ошибки мы напишем проверку, которая будет проверять, является ли мешающее нам окно окном About и в случае, если это так, будем его просто закрывать и помещать сообщение в лог о том, что окно закрылось.

Вот как выглядит изначально наш пример:
 

function TestUnexpectedWindow()
{
  var  wnd;
  wnd = Sys.Process(“calc”).Window(“SciCalc”, “Calculator Plus”);
  wnd.Activate();
 
  wnd.MainMenu.Click(“Help|About Calculator Plus”);
  wnd.Keys(“123″);
  wnd.Window(“Button”, “+”).Click();
}

И вот как выглядит лог запуска этой функции:
 

TestComplete сгенерировал сообщение об ошибке, поместил в лог скриншот мешающего окна и его полное имя, а затем закрыл окно, щелкнув мышью по сфокусированному элементу управления (в данном случае это кнопка OK). После этого TestComplete продолжил выполнение скрипта, однако в логе появилась ошибка, от которой нам хочется избавиться.

Теперь создадим обработчик события OnUnexpectedWindow. Для этого в дереве проекта выберем пункт Events – GeneralEvents, а затем в правой части окна TestComplete дважды щелкнем на пункте OnUnexpectedWindow, как показано на скриншоте ниже.
  

При этом откроется окно New Routine. Здесь мы должны выбрать модуль (Unit), в котором хотим хранить наш обработчик события, а также дать ему имя (по умолчанию GeneralEvents_OnUnexpectedWindow).
  

Обратите внимание! Если вы не выполните все вышеперечисленные действия, а просто создадите функцию с именем GeneralEvents_OnUnexpectedWindow, – это не создаст обработчик события! Чтобы событие перехватывалось, необходимо связать какую-то функцию (новую или существующую) с этим событием, что мы сейчас и делаем.

Мы рекомендуем хранить все обработчики событий в отдельном модуле, например _Events (подробнее о работе с несколькими модулями в проекте можно прочитать в главе 3.10 Работа с несколькими модулями).

Так как у нас нет сейчас отдельного модуля, мы его создаем с помощью кнопки New Unit, а затем жмем ОК в окне New Routine. При этом в модуле _Events у нас появляется функция-обработчик события OnUnexpectedWindow:
 

function GeneralEvents_OnUnexpectedWindow(Sender, Window, LogParams)
{
 
}

В этой функции 3 параметра:

  • Sender (отправитель) – в нашем случае это GeneralEvents
  • Window – окно, которое мешает TestComplete-у
  • LogParams – текущие параметры лога (шрифт, цвет и т.п.)

 

Теперь нам необходимо внести такие изменения, которые позволят не выводить сообщение об ошибке в случае окна About, а просто закрывать его, а в остальных случаях действовать как обычно. Для этого мы будем проверять заголовок окна About, а также воспользуемся свойством LogParams.Locked для блокировки отправки сообщения.
 

function GeneralEvents_OnUnexpectedWindow(Sender, Window, LogParams)
{
  if(Window.WndCaption == “About Calculator Plus”)
  {
    LogParams.Locked = true;
    Window.Close();
    Log.Message(“Окно About закрыто”);
  }
}
Результат работы скрипта:
  

Аналогичным образом создаются обработчики других событий, потому мы не будем их рассматривать подробно, а лишь перечислим некоторые из них и дадим общие рекомендации.

В группе Events provided by the Web Testing plug-in находятся события, специфичные для тестирования веб-приложений:

  1. OnWebBeforeNavigate – возникает перед тем, как браузер осуществляет переход на новую станицу
  2. OnWebDownloadFinished – возникает когда страница открылась либо ее открытие было прервано
  3. OnWebDownloadStarted – возникает сразу после того, как началась загрузка страницы
  4. OnWebPageDownloaded – возникает после того, как страница или фрейм загрузились
  5. OnWebQuit – возникает перед тем, как браузер закрывается

В группе HTTP Load Testing Events находятся специфичные для нагрузочного тестирования события: OnLoadTestingRequest и OnLoadTestingResponse, возникают, соответственно, когда TestComplete отправляет HTTP запрос и получает ответ от сервера.

В группе Network Suite events находятся специфичные для распределенного тестирования события.

Test Engine Events – здесь находятся только два события, OnStartTest и OnStopTest, которые возникают при запуске и остановке работы скриптов. Обратите внимание, что эти события срабатывают для каждого теста только в том случае, если группа тестов запущена с помощью Test Items (например, если вы делаете Run Project или Run Project Suite). Если же вы просто запустили функцию, которая в свою очередь вызывает несколько других тестов (функций), то каждое из этих событий сработает лишь один раз (для запущенной функции).

Группа General Events самая большая, здесь содержатся события, связанные с логом TestComplete: OnLogCloseNode, OnLogCreateNode, OnLogError, OnLogWarning и т.п.. Здесь же находятся события, связанные с появлением неожиданных для TestComplete окон (OnOverlappingWindow и OnUnexpectedWindow), OnTimeout – возникает когда истекает время, отведенное для работы скриптов.

И несколько советов по работе с перехватом событий

  1. Перехват событий – очень полезный и мощный инструмент TestComplete, однако с ним надо быть очень осторожным. Например, в использованном примере достаточно вынести строку LogParams.Locked = true за пределы условия if и вы больше не увидите ни одного сообщения о неизвестном окне, хотя они будут появляться и TestComplete будет пытаться их закрыть. Будьте внимательны, когда используете перехват событий
  2. Не зацикливайте события друг на друга и на самих себя. То есть, не пытайтесь внутри обработчика события OnLogError вызвать метод Log.Error и т.п., а также не пытайтесь, например, вызвать Log.Error внутри обработчика OnLogWarning и одновременно с этим в обработчике OnLogError вызвать Log.Warning, так как это приведет к появлению ошибки
      
  3. Помните, что события, связанные с логом (OnLogError, OnLogWarning, OnLogEvent и т.д.) возникают очень часто в ходе работы скриптов, а значит не стоит перегружать их большим количеством кода, так как это может существенно увеличить время работы тестовых скриптов

 

Назад: 11.7 Использование низкоуровневых процедур Содержание Дальше: 11.9 Ассоциации объектов (object mapping)