1.2 Модификация фрейма

Назад Содержание Дальше

В случае небольших окон, или окон с небольшим количеством элементов управления, возможно и нет нужды в модификации записанного окна/винкласса. Однако в случае больших приложений это совсем не так. Во-первых, имена объектам SilkTest дает, ориентируясь на ближайшие надписи (лейблы – labels), а они не всегда располагаются так, как того хотелось бы. Во-вторых, часто имеет смысл изменить теги объектов, если есть вероятность, что в следующей версии тестируемой программы объекты могут сдвинуться внутри окна, либо когда текст возле объекта может меняться (см. в тестовом приложении окно Static Text, Check Box – в них можно изменить подписи к элементам управления).

1.2.1 Именование объектов (controls)

Вот несколько простых правил именования объектов, которые помогут упростить вам жизнь:

  1. Давайте объектам осмысленные имена (это же правило применимо и к переменным в программе). Если у вас в окне находится несколько текстовых полей, которые относятся к чему-то одному (скажем, возле первого из них будет стоять надпись “Даты:”), а рядом с последним полем будет находиться выпадающий список с подписью “День недели:”, то, скорее всего, несколько последних полей будут иметь имена ДеньНедели1, ДеньНедели2 и т.д., а это совсем неудобно. Если вам потребуется заполнить все поля в форме, то вам придется вспоминать, какие из них как называются, а сделать это в случае наличия большого числа описанных окон и/или нескольких приложений трудно. Не ленитесь исправить имена сразу после записи фрейма: вы сделаете это один раз и больше к этому, скорее всего, не вернетесь;
  2. Объектам каждого типа придумайте префиксы и используйте их. Это упрощает доступ к нужным объектам через выпадающий список в редакторе, а также позволяет избежать ненужной путаницы, если в окне имеются несколько объектов разного типа (например кнопка, поле и список), которым логично дать одинаковые имена. Примеры префиксов приведены в таблице 1.1. Кроме того можно упростить этот процесс, написав функцию, которая будет добавлять префиксы автоматически (см. пример такой функции в файле TestAppUtils.inc из прилагающегося архива, название функции – AddPrefixes).

    Таблица 1.1 Примеры префиксов для стандартных видов объектов

     

    Префикс Объекты
    cb CheckBox
    btn PushButton
    lst ComboBox, ListBox, PopupList, ListView
    rlst RadioList
    stat StaticText
    scb ScrollBar
    edt TextField
    plst PageList
    sb StatusBar
    tb ToolBar
    trb TrackBar
    ud UpDown
    tree TreeView
    cw CustomWin
    w MainWin, ChildWin
    d DialogBox

     

  3. Не используйте в качестве имен объектов никакие символы, кроме английских и символа “_”. Во-первых, это не рекомендуется делать в принципе, так как некоторые компиляторы не понимают такие имена переменных. Во-вторых, каждый раз, обращаясь к стандартному свойству или методу, вам придется менять раскладку клавиатуры

1.2.2 Работа с тегами (tags)

Тег – это характеристика, которая уникально идентифицирует окно или любой другой объект в окне. Тег должен быть уникальным, иначе, если в окне описан объект с тегом, который может относиться к двум объектам, при работе тесткейса сгенерируется исключение такого типа:
*** Error: Window ‘[MainWin]Test Application’ is not unique
Поэтому правильно выбранный тег позволит реже менять фреймы.

Тег может описываться двумя способами:

  • собственно tag
  • multitag (мультитег)

Мультитег описывает несколько тегов, которые могут быть у объекта, поэтому мультитег более универсален.

 

Пример тега:

Code

[-] window MainWin wTestApp
	[-] tag "Test Application"

Пример мультитега:

Code

[-] window MainWin TestApplication
	[+] multitag "Test Application"
		[ ] "$C:\Program Files\Segue\SilkTest\testapp.exe"

Однако конструкция описанного мультитега равносильна следующему описанию:

Code

[-] window MainWin wTestApp
	[-] tag "Test Application|$C:\Program Files\Segue\SilkTest\testapp.exe"

То есть элементы мультитега можно перечислить в теге, разделив их знаком “|” (вертикальной черты). Поэтому в дальнейшем для простоты речь будет вестись о тегах.

 

Совет
По умолчанию SilkTest настроен таким образом, чтобы записывать мультитеги. Это можно исправить в меню Options – Recorder – Record Multiple Tags, или непосредственно во время записи деклараций окна Record – Window Declarations – Options – Record Multiple Tags. Там же можно указать, какой именно способ записи тега использовать по умолчанию.

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

 

Существует 5 способов задания тега объекту:

  1. Caption (заголовок или подпись объекта) – это текст, который непосредственно связан с объектом и как его видит пользователь (например, надпись на кнопке, подпись для флажка и т.д.). Это наиболее употребляемый способ описания объектов, поэтому рекомендуется при записи фреймов использовать именно его.
    Например: tag “OK” – тег для кнопки ОК.
  2. Prior text (ближайший текст) – ближайший к объекту текст сверху или слева от него. Задается с помощью символа “^” (крышка) перед текстом.
    Например: tag “^Ближайший текст:”
  3. Index (порядковый номер) – порядковый номер объекта в окне. Нумерация объектов каждого типа ведется слева направо и сверху вниз. Объявляется с помощью символа “#” (решетка) и номером объекта.
    Например: tag “#4″ – может обозначать четвертую кнопку, или четвертый список, или что-либо еще, в зависимости от того, в объекте какого типа этот тег описан.
  4. Window ID (уникальный номер объекта) – это номер, специфичный для любого GUI-объекта. Задается с помощью символа “$” (знак доллара) и собственно номера объекта.
    Например: tag “$3156″.
    В процессе разработки и изменения приложения эти номера могут меняться, поэтому их следует использовать в самом крайнем случае, если другие описания неуникальны или же попросту невозможны.
  5. Location (месторасположение) – положение объекта относительно его предка, задается координатами X и Y, заключенными в скобки с предыдущим символом @.
    Например: tag “@(84,12)”.
    Этот способ также рекомендуется применять лишь в самых крайних случаях (например, в случае нестандартного элемента управления), так как положение объекта может меняться еще чаще, чем его Window ID.

 

Кроме того, в тегах могут использоваться:

  1. Символы групповой замены (wildcard) – символ “*” (звездочка) заменяет любое количество символов, символ “?” (вопросительный знак) заменяет один символ. Это нужно в тех случаях, когда часть тега может меняться (например, заголовок окна содержит имя файла).
    Пример тега для окна блокнота: tag “* – Notepad”.
    В этом теге указывается, что первая часть окна может быть любой, но окончание должно быть всегда одинаковым. Другой пример: tag “Button?”. В этом теге указывается, что начало заголовка всегда будет одинаковым, а в конце может быть один любой символ (например, “1”, “:”, “Х” и т.д.).
  2. Уже упоминавшийся символ “|”. В теге перечисляются все варианты тегов, которые может иметь объект.
    Например, для кнопки “Отмена” в окне MessageBox может быть определен такой тег: tag “Cancel|Отмена|#3|#2″.
    Первая часть для англоязычной версии Windows, вторая для русскоязычной, третья – для окна с тремя кнопками (Да, Нет, Отмена), четвертая – для окна с двумя кнопками (ОК и Отмена). Последние два варианта будут работать для любой версии Windows. Здесь необходимо учесть, что ставить тег #2 перед тегом #3 нельзя, так как в случае окна с тремя кнопками этот тег будет использован для кнопки “Нет”.
  3. Непосредственное указание класса объекта. Указывается имя класса, заключенное в квадратные скобки (“[” и “]”), ставится перед собственно тегом. Например для той же кнопки тег будет выглядеть так:
    tag “[PushButton] Cancel|Отмена|#3|#2″.
    Такие конструкции используются, если в окне есть два объекта с одинаковыми тегами и этот объект непосредственно не описан в окне, а лишь является составной частью тега (см. ниже описание символа “/”).
  4. Символ “/” (слеш). Служит для разделения классов в теге. Предположим, что в окне, которое нам нужно описать, имеется несколько уровней вложенности объектов, часть из которых нас не интересует, то есть работать с ними нам не нужно.
    Например, в диалоговом окне есть набор вкладок, на каждой вкладке определено еще одно диалоговое окно, невидимое для пользователя, но видимое для SilkTest-а, и уже в этом самом диалоговом окне находится кнопка “Старт”, единственная, которая нам нужна. Если оставить фрейм в таком виде, как его записывает SilkTest, нам для нажатия на кнопку придется написать что-то в таком роде:

     

    Code

    Dialog1.PageList1.Dialog1.Start.Click ()
    

    Однако писать такое каждый раз утомительно, а читать подобный код будет неудобно. Гораздо проще переместить кнопку “Старт” на один уровень с набором вкладок (используя сочетание клавиш Alt+Влево) и задать кнопке такой тег:
    tag “[PageList]#1/[DialogBox]#1/[PushButton]Старт”
    После этого нажатие на кнопку будет выглядеть таким образом:

    Code

    Dialog1.Start.Click ()
    

     

  5. Символы “..” (две точки). Используются для указания предка данного объекта. Проще всего пояснить на примере.
    Есть окно, у которого постоянно меняется Window ID, местоположение и заголовок, однако у него гарантированно всегда есть кнопка “Print”.
    Тег для этого окна будет таким:
    tag “[PushButton]Print/..”
    Обратите внимание: это НЕ тег кнопки, а тег окна, который содержит такую кнопку.

    Другой пример: та же кнопка, но находится она всегда в диалоговом окне, который находится на наборе вкладок, а набор вкладок находится в нашем окне, для которого нужен тег.
    Он описывается так:
    tag “[PageList]#1/[DialogBox]#1/[PushButton]Старт/../../..”

  6. “~ActiveApp”. Указывает, что предок самого высокого уровня данного объекта в настоящий момент активен.
    Такой тег используется, например, для описания MessageBox, так как его непосредственный предок может быть любым (сравните предков для этого окна в TestApplication в двух случаях: когда оно вызывается через меню Menu – The Item, предком является главное окно приложения, когда же оно вызывается из любого диалогового окна, например Check Box, нажатием кнопки Popup, то предком будет это диалоговое окно).
    Также такой префикс необходимо указывать для диалоговых окон, которые не имеют главного окна (например, окна при установке некоторых программ: Microsoft Office, Acrobat Reader).
    Пример тега для таких программ:
    tag “~ActiveApp/[DialogBox]Установка Microsoft Office*”
  7. Номера объектов с одинаковыми тегами.
    Указывается в конце тега, заключается в квадратные скобки.
    Например, если у нас открыто несколько окон TestApplication, то при попытке обратиться к нему возникнет исключение
    *** Error: Window ‘[MainWin]Test Application’ is not unique
    Однако можно исправить тег окна, чтобы такая ошибка не возникала:
    tag “Test Application[1]”
    Чтобы теперь закрыть все окна TestApplication в тесткейсе, достаточно будет написать

     

    Code

    [-] while wTestApp.bExists
    	[ ] wTestApp.Close ()
    

     

  8. Символ “~” (тильда). Ставится в начале мультитега. Указывает SilkTest-у, что надо проверять и вторую часть мультитега (по умолчанию если первая часть совпадает, то вторая часть не проверяется).
    Пример:
    tag “~Test Application|$C:\Program Files\Segue\SilkTest\testapp.exe”
    Если изменить в этом теге его вторую часть, то SilkTest не увидит приложение. Если после этого убрать тильду в начале тега, то приложение снова будет доступно.

 

Еще некоторые замечания по тегам.

В тегах можно использовать вызовы функций. Например, если у какого-то окна заголовок представляет собой текущую дату в формате “Сегодня дд/мм/гггг” (дд, мм, гггг – день, месяц и год), то целесообразно для этого окна указать такой тег:
tag “Сегодня {FormatDateTime (GetDateTime (), “dd/mm/yyyy”)}”

Учитывая этот факт, а также то, что в классах SilkTest-а отсутствует понятие конструктора и деструктора, можно добавить к тегу вызов функции, которая будет возвращать пустую строку, но при этом выполнять действия, которые должны выполняться в конструкторе:

Code

[-] string Constructor ()
	[ ] // Какие-то действия конструктора...
	[ ] return ""
[-] window MainWin wTestApp
	[ ] tag "{Constructor ()}Test Application[1]"

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

1.2.3 Выделение общих винклассов

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

Если внимательно посмотреть на окна, которые вызываются из меню Control приложения Test Application, можно выделить следующие общие элементы управления:

  • кнопка Exit
  • кнопка Popup
  • чекбокс Enabled

 

Эти три элемента лучше выделить в отдельный винкласс, а затем все окна, содержащие эти элементы, пронаследовать от этого класса.
Для этого есть несколько причин:

  1. мы избегаем повторяемости кода (описываем только один раз эти элементы)
  2. получаем возможность написания методов для этого винкласса, которые будут доступны для всех окон
  3. в случае изменения приложения (например, кнопка Exit изменит название на Close) нам будет достаточно сделать изменения один раз
  4. улучшается тестирование (например, кнопка Exit изменится на Close во всех окнах, кроме одного; скорее всего, это будет неправильно)

 

Полученный класс будет иметь следующий вид:

Code

[-] winclass TestApp_Controls : DialogBox
	[ ] parent wTestApp
	[+] PushButton btnExit
		[ ] tag "Exit"
	[+] PushButton btnPopup
		[ ] tag "Popup"
	[+] CheckBox cbEnabled
		[ ] tag "Enabled"

Как видно, кроме объявления в винклассе элементов управления, в нем же объявлен предок: parent wTestApp. Теперь его не н ужно объявлять в каждом окне.
Теперь описания окон, наследующихся от этого класса, будут выглядеть так:

Code

window TestApp_Controls dCheckBox

и т.д.

Примечание. В SilkTest-е версий до 7.5 есть ошибка: при обращении к элементам управления, которые помещены в класс, как это сделано у нас, доступ к этим элементам не виден в выпадающем списке в окне редактора. Это может проявляться в некоторых случаях при большой вложенности классов.

В качестве примера посмотрите метод CheckPopup(), определенный в созданном винклассе TestApp_Controls (файл TestApp.inc). Этот метод проверяет, что при нажатии на кнопку Popup, появляется сообщение. Также посмотрите тесткейс Test_Winclass_Method() (файл TestApp.t)


Назад Содержание Дальше