Mapping
TestComplete ( JScript ): Описание оконных деклараций через классы-обертки
Опубликовано KaNoN в 05.08.2010Автоматизированное тестирование на уровне GUI содержит в себе много сюрпризов, связанных с работой с оконными объектами. Причем сюрприз заключается в том, что наиболее изящное решение проблемы с поддержкой описаний оконных объектов в актуальном состоянии для каждого отдельно взятого средства может быть свое. Но это наиболее удачное решение. Тем не менее, есть ряд механизмов, имеющих аналоги в различных средствах. Одним из примеров является Mapping оконных деклараций, позволяющий некоторым оконным объектам ставить в соответствие некоторый псевдоним. Подобное решение в TestComplete обладает одним ключевым недостатком: при изменении иерархии оконного объекта приходится переделывать маппинг всех дочерних объектов. Альтернативой этому стало введение с 6-й версии TestComplete такой функциональности как Alias, которая позволяла регулировать иерархию псевдонимов. Но у такого решения есть другой недостаток: низкая скорость. Соответственно, нужны механизмы, позволяющие оперативно реагировать на изменение GUI, при этом корректировки желательно минимизировать. Давайте рассмотрим конкретный пример.
У нас есть некоторое диалоговое окно, к которому в коде можно обратиться так:
Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1);Здесь PRODUCT_NAME - это некоторая константа, содержащая в себе имя процесса. В вышеуказанном диалоге есть текстовое поле Name , к которому обратиться можно так:
Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1).Window( "TEdit" , "*" , 1 );а также 2 кнопки: OK, Cancel, у которых описания имеют вид соответственно:
Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1).Window( "TButton", "*", 1 )
Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1).Window( "TButton", "*", 2 )Как видно из описаний, объекты не очень компактно описаны, более того, достаточно нестабильно, поскольку используются индексы. Часто может возникнуть ситуация, когда имена объектов в разной среде разные. Самый простой пример: системные окна сообщений для разных локализаций операционной системы имеют кнопки с текстом на локальном языке. Если заказчик из англоязычной страны, то проблем не возникнет. Но если же автотесты создаются для продукта, который идет и для неанглоязычных потребителей, то тут надо уменьшить привязку к тексту объектов, что было сделано для объектов выше. Теперь, давайте рассмотрим некоторый типичный тестовый сценарий, использующий эти объекты. Допустим нам надо подождать появления диалога в течение 5 секунд. Если он появился, то вводим текст ( неважно какой ) в текстовое поле Name и жмем кнопку OK. В чистом виде это выглядит так:
if( Sys.Process("Inventory").WaitWindow("TForm", "New Text Style", 1 , 5000 ).Exists ) {
Log.Error( "No Text Style dialog available" );
}
else {
Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1).Window( "TEdit" , "*" , 1 ).wText = "Some Text";
Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1).Window( "TButton", "*", 1 ).Click();
}Первое, что бросается в глаза - это громоздкость кода. Слишком длинные конструкции. Далее, можно представить, что случиться, если поменяются атрибуты диалогового окна, например, текст заголовка. В результате, данный объект будет требовать несколько другого описания, из-за чего надо будет редактировать обращения и к элементам управления внутри диалога. Если прибавить к этому тот факт, что подобных конструкций в тестах может быть много и разбросаны они по разным частям файлов, то при необходимости корректировки оконных деклараций объем исправлений будет значительным. Как минимизировать требуемый объем исправлений. Одним из решений будет предоставление интерфейса для работы с окнами, который инкапсулирует непосредственное обращение к объектам. То есть можно создать класс, методы которого обеспечат доступ к нужным элементам. Итак, сделаем класс-обертку и предоставим возможность доступа непосредственно к диалоговому окну. Выглядит это так:
function NewTextStyleDlg()
{
this.Get = function ()
{
return Sys.Process( PRODUCT_NAME ).Window("TForm", "New Text Style", 1);
}
}Уже получили уменьшение кода, более того, данный фрагмент уже требует заметно меньших модификаций в случае изменения свойств диалогового окна.
var dNewTextStyle = new NewTextStyleDlg();
if( Sys.Process( PRODUCT_NAME ).WaitWindow("TForm", "New Text Style", 1 , 5000 ).Exists ) {
Log.Error( "No Text Style dialog available" );
}
else {
dNewTextStyle.Get().Window( "TEdit" , "*" , 1 ).wText = "Some Text";
dNewTextStyle.Get().Window( "TButton", "*", 1 ).Click();
}»
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
- Читать далее







