^^f^^%mm\t^,.r
••x.:.-x..... .«g^ M * 1*^1 > *«?'=•*
m
^ ^
жч-
/,.'70
^jj^h 1 -,,
'••«•«til
Ai//j u/= ]u\
l^nifTBP'
••
и. Винниченко
АВТОМАТИЗАЦИЯ ПРОЦЕССОВ ТЕСТИРОВАНИЯ
^ЯЯГ/ЕР' Москва • Санкт-Петербург • Нижний Новгород - Воронеж Ростов-на-Дону • Екатеринбург • Самара Киев - Харьков • Минск
2005
ББК 32.973.2-07 УДК 004.415.53 В51
Винниченко И. В. В51 Автоматизация процессов тестирования. — СПб.: Питер, 2005. — 203 с : ил. ISBN 5-469-00798-7 Книга посвищсла вопросам практического применения автоматизации тестирования, которое является одним из важнейатх аспектов обеспечения качества программных продуктов. В пей дается детальное о[1исание программ ных средств, необходимых лчя повседневной работы в этой облас'1и, с указа нием конкрет1и>1х функций и методов грех ведущих поставщиков ПО дщя авто матизации тестирования: Segue SilkTest, Mereui-y Interactive WinRunner и Ratio nal Robot. В список тем также входят Record/Playback, языки скриптов, функции работы с объектами графического интерфейса пользовалеля, функции работы с базами данных, методы обработки исключительных сичуаций и управление процессом исполпе1шя. Структура книги позволяет использовать ее, с одной стороны, как пособие для знакомства с азами автоматизации тестирования, а с другой стороны как помощника в повседневной работе.
ББК 32.973.2-07 УДК 004.415.53
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав. Информация, содержащаяся в данной книге, получена из источников, рассматриваемых издательством как надежные. Тем не менее, имея в виду возможные человеческие или технические ошибки, издательство не может гарантировать абсолютную точность и пол ноту приводимых сведений и не несет ответственности за возможные ошибки, связанные с использованием книги.
ISBN 5-469-00798-7
© ЗАО Издательский дом «Питер», 2005
Краткое содержание Предисловие
13
Глава 1 . Основы автоматизации
15
Глава 2. Record/Playback
26
Глава 3. Язык скриптов
38
Глава 4. Элементы интерфейса и их функции . . . 73 Глава 5. Вспомогательные функции
107
Глава 6. Функции работы с базами данных . . . . 133 Глава 7. Обработка ошибок
143
Глава 8. Функции пользователя
148
Глава 9. Управление процессом исполнения . . . 159 Приложение А. Работа с нестандартными объектами в Silkiest Приложение Б. Работа с нестандартными объектами в WinRunner Приложение В. Автоматизация приложения Pizza Order средствами Silkiest и WinRunner Алфавитный указатель
164 167 169 199
Содержание Предисловие
13
От издательства
14
Глава 1 . Основы автоматизации
15
Тестировщик: профессионал или обслуживающий персонал?. . . 15 Черный ящик, белый ящик 18 Что такое автоматизация и с чем ее едят? 19 С чего начинается автоматизация 21 Из чего же, из чего же, из чего же сделана наша автоматизация 24
Глава 2. Record/Playback
26
Как устроена автоматизация WinRunner Выполнение записи Среда выполнения Библиотека объектов Средство опознавания объектов SilkTest Библиотека объектов Выполнение записи Среда выполнения Средство опознавания объектов Rational Robot Выполнение записи Среда выполнения
26 27 27 28 29 31 32 32 33 34 34 35 35 36
Содержание
Библиотека объектов Средство опознавания объектов
37 37
Глава 3. Язык скриптов
38
Переменные TSL (WinRunner) 4TEST (Silkiest) SQABasic (Robot) Массивы данных TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Операторы TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Логические операторы TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Операторы сравнения TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Условные операторы TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Операторы цикла TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Функции приведения типов TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot)
38 39 41 42 43 44 44 45 46 46 46 47 47 47 47 48 48 48 48 48 49 49 51 52 53 53 54 55 56 57 57 58
8
Содержание
Функции работы с массивами TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot) Ф у н к т т работы со строками TSL (WinRunner) 4TEST (SilkTest) SQABasic (Robot)
59 59 59 62 64 64 66 69
Глава 4. Элементы интерфейса и их функции . . . 73 Window Активирование окна Сворачивание окна Разворачива}П1е окна Восстановление первоначального вида окна Menu
74 74 75 75 76 77
Выбор элемента из списка Выбор элемента из списка в субуровне другого элемента ... ListBox/ComboBox Выбор элемента списка по его значению Выбор элемента из списка по его порядковому номеру . . . . Выбор нескольких элементов из списка по их значениям ... Выбор нескольких элементов из списка по их порядковым номерам
77 78 79 80 80 81
Определение порядкового номера элемента списка по его значению Определение значения элемента списка по его порядковому номеру Определение количества элементов в списке Определение значения всех элементов в списке Определение значения выбранного элемента списка Button Нажатие кнопки Получение сведений о состоянии элемента CheckBox/RadioButton Выбор параметра
82
82 83 83 84 85 85 86 86 87 87
Содержание
9
Отмена выбранного параметра Получение информации о состоянии элемента Button EditBox Ввод информации в поле ввода Возможность очистить элемент от предыдущего ввода Получение текущего значения в поле ввода Table Получение количества строк в таблице Получение количества столбцов в таблице Возврат значений заголовков таблицы Получение значения произвольной ячейки таблицы Получение координаты произвольной ячейки таблицы по ее значению Scroll Перемещение в начало окна/документа Перемещение в конец окна/документа Перемещение на фиксированное расстояние внутри окна документа Перемещение на одну страницу/экран выше/ниже Tab Перемещение от одного элемента Tab к другому по его значению Получение количества вкладок, содержащихся в Tab Перемещение от одного элемента Tab к другому по его порядковому номеру Label Image button Link
. 88 89 90 91 92 92 93 93 94 95 96
Глава 5- Вспомогательные функции
107
Функции имитации клавиатурного ввода WinRunner SilkTest Rational Robot Функции имитации действий, выполняемых мышью WinRunner
107 108 108 110 111 112
97 97 98 98 99 100 101 101 102 103 103 104 105
1о
SilkTest Rational Robot Функции работы с системой WinRunner SilkTest Rational Robot Функции оповещения о результатах WinRunner SilkTest Rational Robot Функции синхронизации WinRunner SilkTest Rational Robot Функции проверки существования объекта WinRunner SilkTest Rational Robot Функции работы с файлами WinRunner SilkTest Rational Robot Практический пример 1 WinRunner SilkTest Rational Robot
Содержание
ИЗ 114 117 117 118 119 120 120 121 121 122 123 123 124 124 124 125 125 126 126 127 129 130 131 131 132
Глава 6. Функции работы с базами данных .... 133 WinRunner SilkTest Rational Robot Практический пример 2 WinRunner SilkTest Rational Robot
.134 136 138 140 141 141 142
Содержание
11
Глава 7. Обработка ошибок
143
WinRunner SilkTest. Rational Robot
144 144 146
Глава 8. Функции пользователя
148
WinRunner SilkTest Rational Robot Практический пример 3 WinRunner SilkTest Rational Robot
149 150 151 152 153 154 156
Глава 9. Управление процессом исполнения ... 159 Вызов тест-скриптов из мастер-скрипта WinRunner SilkTest Rational Robot Загрузка/выгрузка библиотеки функций WinRunner SilkTest Rational Robot Загрузка/выгрузка библиотеки объектов WinRunner SilkTest Rational Robot
Приложение A. Работа с нестандартными объектами в SilkTest
160 160 160 161 161 . . . . 161 162 162 162 162 163 163
164
Набор графических объектов распознается как один о б ъ е к т . . . 164 Объект не распознается вообще и требует написания методов работы с ним с нуля 165 Объект распознается как нестандартный класс, но может быть передекларирован как стандартный 166
12
Содержание
Приложение Б. Работа с нестандартными объектами в WinRunner Объект не распознается и требует написания методов работы с ним с нуля Объект имеет текстовый определитель, который незначительно изменяется с каждым вызовом программы тестирования Объект распознается как нестандартный класс, но может быть передекларирован как стандартный
167 167 168 168
Приложение В. Автоматизация приложения Pizza Order средствами Silkiest и WinRunner Бизнес-спецификация Функциональная спецификация Техническая спецификация Тестовая документация Структура автоматизации WinRunner SilkTest
169 169 169 170 178 180 180 192
Алфавитный указатель
200
Предисловие
Идея создания этой книги появилась у меня довольно давно. На про тяжении длительного времени меня очень расстраивал тот факт, что такая обшир1{ая тема компьютерных наук, как автоматизация про цессов тестирования, остается не охваченной печатным словом. Это верно как для безбрежхюго моря англоязычных публикащп! на компью терные темы, так и для российского книжного рынка. И хотя вышло несколько публикаций по теории автоматизации, нет ни одной книги, которая бы взяла «читателя за руку» и показала, как начать и с чего начать. Книги, которая на примерах реально суш;ествующих программ показала бы, что же все-таки кроется за этим труднопроизносимым термином — программные средства автоматизации процессов тести рования. Книги, которую бы мне хотелось иметь, когда я сам изучал премудрости этого ремесла в оптоволоконных дебрях Силиконовой Долины. Окончательно в необходимости создания такой книги и в том, что она может быть востребована в России, я убедился, когда, бороздя просторы Интернета, зашел на российский сайт поиска работы. Вро жденная любознательность заставила меня задать поиск по параметру QA/Tester. Сказать честно, я был очень удивлен количеством пред лагаемых вакансий. Я что называется «вживую» увидел, что процесс глобализации пустил в России корни и такая вещь, как Software Development Outsourcing все больше и больше входит в экономиче скую жизнь страны. Там же, где разрабатывается программное обес печение, если это, конечно, серьезная разработка приложений мирово го уровня, требуется наличие многочисленных и знающих инженеров по качеству. Там же, где проходит тестирование, должна быть воз можность это тестирование автоматизировать. Я думаю, что в совре менном мире нет необходимости объяснять важность автоматизации чего бы то ни было, особенно когда речь идет о таком мощном сред стве улучшения качества и уменьшения затрат разработки про граммного обеспечения, как автоматизация процессов тестирования.
14
Предисловие
Поэтому очень надеюсь, что эта книга окажется полезной людям, за нимающимся проверкой качества выпускаемого ПО. Эта книга создавалась как практический справочник, одинаково год ный как для освоения материала, так и для быстрого восстановле ния в памяти необходимой информации. В ней затронуты такие темы, как Record/Playback, основные элементы графического интерфейса пользователя и функции работы с ними, функции работы с базой дан ных и инструменты обработки ошибок. Эти темы являются актуаль ными, какое бы средство автоматизации тестирования вы не исполь зовали и какое бы программное обеспечение вам не приходилось тес тировать. В книге рассматриваются три программных продукта — WinRunner, SilkTest, Rational Robot, являющихся лидерами рынка автоматизации процессов тестирования. И рассматриваются они в контексте общей концепции автоматизации тестирования. Подобный подход при всей его привлекательности имеет одно «но»: некоторая специфическая функциональность программ может оказаться не от раженной. Вместе с тем я не пытался объять необъятное и создать абсолютно полное практическое пособие. Основная моя цель была помочь оценить важность автоматизации, раскрыть ее возможности, дать основу знаний в области автоматизации процессов тестргрования, привести примеры решенР1я возникающих проблем. Надеюсь, что эта книга окажется для вас полезной и послужит надежным лоцма ном в море автоматртзированного тестирования программного обес печения.
От издательства Ваши замечания, предложения и вопросы отправляйте по адресу электронной почты
[email protected] (издательство «Питер», компью терная редакция). Все исходные тексты, приведенные в книге, вы можете найти по ад ресу: http://www.piter.comdownloacl. Мы будем рады узнать ваше мнение! Подробную информацию о наших книгах вы найдете на веб-сайте издательства: http://www.piter.com.
Глава 1 Основы автоматизации
В этой главе, пожалуй единственной из всех, поговорим о теории, а не о практике. Профессия тестировщика программного обеспече ния, как и ее сестра — профессия инженера по качеству, а также «выросшая» из них профессия инженера по автоматизации процессов тестирования, очень молода и зачастую овеяна мифами и подверже на влиянию предрассудков. Эта профессия, появившаяся в Соеди ненных Штатах Америки больше 15 лет назад, даже там не пользу ется большим уважением у программистов — «белой кости» 1Т-мира. Заслуживают ли специалисты в этой области подобного отношения? Что представляет собой тестировщик, QA (инженер по качеству), Automation Developer? Что представляет собой автоматизация про цессов тестирования? Каковы ее основные принципы? На эти вопро сы постараемся ответить в данной главе. Итак, начнем...
Тестировщик: профессионал или обслуживающий персонал? Давайте проведем небольшой экскурс в прошлое — зададим простой вопрос: «Когда это все началось?» Думаю, мало кто в мире высоких технологий будет отрицать, что бизнес программного обеспечения как массовый феномен появился благодаря Биллу Гейтсу. Да, до него бы ли Sun Microsystems, IBM и Unix. Да, до него суш[ествовали вычис лительные лаборатории в СССР, США и Японии. Да, до него писа лись (и тестировались) программы. Но давайте посмотрим правде в глаза: именно Windows при всех своих неисчислимых дефектах по служила тем камнем, который породил лавину компьютеризации на нашей планете в той ее форме (компьютер в каждом доме и офисе), в которой она существует сейчас. И хотя я хорошо понимаю огром ное количество людей, сочинявших и продолжающих сочинять бес-
16
Глава 1. Основы автоматизации
численные анекдоты про Билла Гейтса, нельзя не отдать должного этому человеку. Так вот, и профессия «тестировщик программного обеспечения» родилась в недрах именно Microsoft. Когда товарищ Гейтс решил потеснить махину Sun Microsystems и весь лагерь Unix как таковой на рынке операционных систем для серверов, создав Win dows NT, он пришел к здравому заключению. Бороться с ОС, кото рую писали и отлаживали десятки тысяч человек, можно лишь про тивопоставив им свою армию спецов. Но программисты, особенно когда их много и они работают над гигантским проектом, не способ ны следить за качеством выпускаемой продукции. И вот именно для создания конкурентоспособной ОС и была «создана» группа людей, ответственных за тестирование и качество конечного продукта. Вот мы и подошли к вопросу о том, кто же такой тестировщик, чем он занимается и чем он отличается от инженера по качеству. Итак, тестировщик — это человеку оценивающий программный продукт с точки зрения пользователя. Собственно, его задача заключается в подтверждении того, что человек, впервые видящий и использую щий программу, будет в состоянии полностью использовать ее функциональность, не испытывая при этом неудобства от «зависа ния» системы, появления сообщений об ошибках, ни с того ни с сего закрывающихся окон и прочих «прелестей», которыми изобилуют многие программные продукты. В его обязанности входит также проверка того, что программный продукт делает именно то, что он должен, и так, как он это должен делать. Ситуация, когда пользо ватель щелкает на кнопке Печать, а вместо отправки документа на принтер он просто сохраняется, является неприемлемой для хорошо протестированного продукта. Инженер по качеству — это тот же тестировщик, только ответственный за качество продукта в тече ние всего цикла разработки. Давайте взглянем на типичную схему та кого цикла. Как видно из этой схемы, отдел разработки бизнес-требований (ОРБТ) (Product Specialists) предоставляет группе тестирования (QA) и группе программистов (Development) два документа: BRD (Bu siness Requirement Document), описывающий бизнес-логику выпус каемого продукта, и FDD (Functional Design Document), описываю щий функциональные требования к выпускаемому продукту. После того как программисты рассмотрят эту документацию, они создадут еще один документ — TDD (Technical Design Document), который затем будет отправлен на рассмотрение в отдел разработки бизнестребований и группе тестирования. После его рассмотрения и утвер-
Тестировщик: профессионал или обслуживающий персонал?
17
ждения отделом разработки бизнес-требований группа тестирования приступает к написанию тест-плана, тест-сценариев и тест-кейсов, которые послужат основой для дальнейшего тестирования продукта. Тем временем программисты пишут код. Когда код становится отно сительно стабильным, его начинает тестировать группа тестирования. В ходе тестов обнаруживаются дефекты, программисты их исправ ляют, и так продолжается до тех пор, пока продукт не приобретает должную стабильность или не начинают поджимать сроки. Вот, соб ственно, и весь цикл разработки «в разрезе».
Зона ответственности инженера по качеству начинается во время чте ния BRD и FDD. В его обязанности входит не только и не столько тестирование непосредственно кода, сколько проверка того, что ка чество всех компонентов (а в особенности документации) программ ного продукта находится на высоте. То есть если ОРЕТ пишет чтото заведомо неосуществимое или не дружественное пользователю, инженер по качеству должен забить тревогу. В его обязанности вхо дит и рассмотрение TDD — если он знает, что пользователю необхо димо будет иметь открытыми несколько окон, каждое из которых должно регулярно производить чтение/запись базы данных, то его долг Цастоятельно рекомендовать не использовать такие громозд кие по времени исполнения вещи, как JavaApplets и JDBC «в одном флаконе». Если инженер по качеству знает, что строчная длина ка-
18
Глава 1. Основы автоматизации
кого-то поля должна превышать длину, описанную в TDD (напри мер, в поле «Город» значение «Комсомольск-на-Амуре» должно быть видно целиком), то он обязан об этом сообщить до начала кодиро вания. Даже такие элементы программы, как цветовая гамма и ис пользуемые шрифты, входят в зону ответственности инженера по качеству. Никто не требует от него быть специалистом в графиче ском дизайне или гуру в программировании на C++, но все, что ка сается удобства использования в будущем и качества программного продукта, должно сразу бросаться ему в глаза. Как уже, надеюсь, ясно, профессии тестировщика и инженера по ка честву (в дальнейшем QA) являются очень важными и нужными в современном 1Т-мире. Профессионалам в этой области следует быть не только компьютерно грамотными (в том числе знать языки про граммирования — но об этом позже), но и уметь «увидеть» продукт глазами пользователя, а также быть очень внимательными к дета лям. Нельзя забывать и о том, что хороший инженер по качеству — это хороший дипломат. Ведь если смотреть правде в глаза, далеко не каждый легко согласится признаться в том, что он где-то допустил ошибку, которую вы потом обнаружили. Верно?
Черный ящик, белый ящик в классической, если ее можно так назвать, интерпретации сущест вуют два основных метода тестирования: с открытым (whitebox tes ting) и с закрытым (ЫаскЬох testing) кодом. Некоторые переводчики буквально переводят эти термины как «тестирование черного ящи ка» и «тестирование белого ящика». Не будем дискутировать на эту тему, а просто для данной главы примем мой перевод этих терми нов. Итак, как и следует из названия, тестирование с открытым кодом про исходит тогда, когда QA непосредственно «видит» код программно го продукта. В этом случае инженер рассматривает код, написанный программистом, и вносит свои поправки (например, «Если значе ние этой переменной выйдет за рамки, поставленные руководством пользователя, этот цикл станет бесконечным» или «При подключе нии к базе данных из этого метода по его завершении это подключе ние не освобождается, что приведет к тому, что после N-ro вызова метода подключение к базе данных станет невозможным»). Как легко догадаться, человек, способный проводить анализ подобного рода, должен являться как специалистом в области тестирования (он дол-
Что такое автоматизация и с чем ее едят?
19
жен уметь «увидеть», что может «отчебучить» пользователь), так и высококлассным программистом. Зачастую к обязанностям whitebox QA относят и написание так называемых модульных тестов (unit tests). Но это отдельная тема, которой в данной книге касаться не будем. Тестирование с закрытым кодом является наиболее распространен ным и, как опять-таки следует из названия, не предполагает возмож ность доступа QA к исходному коду программного продукта. В пол ном объеме такое тестирование описано в разделе «Тестировщик: профессионал или обслуживающий персонал?». К счастью Р1ЛИ к сожалению, ничто в этом мире не является абсо лютно белым или же абсолютно черным. Так и в области тестирова ния существует понятие тестирования с полуоткрытым кодом (graybox testing). Сюда как раз и попадает автоматизация процессов тестирования. Полуоткрытый код подразумевает, что тестировщик знаком с архитектурой (например, со стандартной схемой индустри альных (enterprise level software) приложений: Oracle — WebLogic — JavaApplet) программного продукта; что он может зайти на сервер и посмотреть журнал исполнения; что он знает структуру модели дан ных этого представляемого программного продукта и в случае чего — сможет написать SQL-запрос для подтверждения результатов, выдан ных программным продуктом (ПП). То есть он как бы и не специа лист в программировании (как whitebox QA), но уже и не просто тестировщик. На самом деле, все три направления тестирования должны курировать специалисты именно этого направления.
Что такое автоматизация и с чем ее едят? Автоматизация в теории представляет собой мечту Сыроежкина из книги «Приключения Электроника»: «Вкалывают роботы, а не чело век». Зачастую работа тестировщика превращается в одну большую, длинную лямку. Это происходит на стадии перепроверочного тести рования (regression testing). Так называется тестирование того, чтобы все, что работало нормально, так и продолжало работать нормально даже после того, как программисты что-то исправили в коде. Нужно провести сотни тест-кейсов, которые перепроверяются каждые N не дель или даже дней. После того как ты 5 раз ввел название «Александровск-Сахалинский» в поле «Города», очень скоро захочется
20
Глава 1. Основы автоматизации
волком выть, не правда ли? Вот здесь и приходит на помощь авто матизация. Специализированныр! программный продукт (в книге мы рассмотрим тройку лидеров: Segue SilkTest, Mercury Interactive WinRunner и Rational Robot) берет на себя всю рутинную работу. Признаться честно, автор еще ни разу не видел человека, который бы не восхитился, впервые увидев «автоматизацию в действии». Ре акции бывают самые разные, но запомнилась мне такая. Как-то один из наших специалистов по продажам проходил мимо моего каби нета и увидел выполняющийся скрипт. Его слова можно перевести так: «В этот компьютер вселилась нечистая сила?» («Is this machine possesed?»). Такие вот веселые вещи происходят в компьютерных компаниях. Так или иначе, хорошо поставленный процесс автома тизации экономит кучу времени и денег. В общем, рай компьютер ный — не так ли? Не совсем. Всегда есть одно «но». Его размеры ме няются в зависимости от ситуации, но оно всегда есть, к сожалению. В случае с автоматизацией этР1м «но» является то, что автоматиза ция работы стоит времени, денег (на лицензии и зарплату) и, конеч но же, очень сильно зависит от квалификации инженерного состава. Так что экономическую целесообразность автоматизацрти можно оп ределить следующей формулой (я не смог нигде найти ее цифрового выражения, да и не уверен, что оно «формально» существует, поэто му даю свою интерпретацию): NT Р " L-^T,P,' где А — коэффициент возврата вложений в автоматизацию; N — ко личество выполнений данного набора тестов в течение цикла раз работки; 7^ — время, затрачиваемое на выполнение набора тестов вручную, ч\ Р^ — зарплата тестировщика в час; L — стоимость лицензии(й) программного обеспечения (ПО) для тестирования; Т^ — время, затраченное на разработку и поддержку автоматизации, ч; Ра — зарплата инженера по автоматизации тестирования ПО в час. Как видно из формулы, Л > 1 будет означать, что автоматизация в данном проекте является экономически оправданной. Хочу также отметить, что данная формула учитывает лишь экономическую вы году для отдела тестирования. При расчетах для всего отдела разра ботки эту формулу нужно переписать следующим образом: ^ А г г , д+р„(7;-7;.) L + TP,
с чего начинается автоматизация
21
где Р„ — зарплата программиста, в час; Г„ — время, затрачиваемое на автоматический набор тестов, в ч. Эта модификация обусловливается тем, что, чем быстрее будет про ведено тестирование, тем быстрее будут найдены дефекты и тем бы стрее программисты приступят к их исправлению, экономя таким образом дополнительное время и деньги.
С чего начинается автоматизация Автоматизация, как бы странно это не звучало, начинается с тести рования вручную. Если быть более точным, то с документации, на писанной для такого тестирования. То есть для того, чтобы начать процесс автоматизирования тестирования, нужно точно знать, что и как вы собираетесь делать. В идеале каждый скрипт должен базиро ваться на ручном тест-кейсе с должным уровнем детализации. Да вайте более детально рассмотрим ситуацию на практическом примере (здесь и далее будут приводиться примеры, использующие простое HTML-приложение Pizza Order, написанное для этой цели). Предположим, необходимо проверить, что каждый тип пиццы мо жет быть заказан как без специальной начинки, так и со всеми воз можными ее (начинки) вариациями.
Pizza Туре г Large [$7.00] С Medium [S6.00] С SmaH [$5.00]
Toppings П Реррегопу [$2.00] П Mushrooms [$1.50] П Meat [$2.50]
Х о р о ш о написанный тест-кейс будет выглядеть с л е д у ю щ и м образом: Выберите вариант Large из списка Pizza Туре Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Mushrooms из списка Toppings Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Meat из списка Toppings
22
Глава 1. Основы автоматизации
Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Mushrooms из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Mushrooms из списка Toppings Подтвердите проверку Выберите вариант Large из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Mushrooms из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Mushrooms из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Mushrooms из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Mushrooms из списка Toppings Подтвердите проверку Выберите вариант Medium из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Mushrooms из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку
с чего начинается автоматизация
23
Выберите вариант Small из списка Pizza Туре Подтвердите проверку Выберите вариант Small из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Подтвердите проверку Выберите вариант Small из списка pizza Туре Выберите вариант Mushrooms из списка Toppings Подтвердите проверку Выберите вариант Small из списка Pizza Туре Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Small из списка Pizza Туре Выберите вариант Mushrooms из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Small из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку Выберите вариант Small из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Mushrooms из списка Toppings Подтвердите проверку Выберите вариант Small из списка Pizza Туре Выберите вариант Реррегопу из списка Toppings Выберите вариант Mushrooms из списка Toppings Выберите вариант Meat из списка Toppings Подтвердите проверку К сожалению, тест-кейс с подобным уровнем детализацрш в реаль ном мире можно встретить очень-очень редко. Наиболее вероятно, что инженеру-автоматизатору будет предоставлен следующий тесткейс: Выберите вариант Large из списка Pizza Туре Поочередно выберите каждую возможную комбинацию в списке Toppings (рассматривая невыбор как одну из возможных комбинаций), выполняя проверку после каждой выбранной комбинации Выполните шаги 1 и 2 для варианта Medium из списка Pizza Туре Выполните шаги 1 и 2 для варианта Small из списка Pizza Туре
Намного более общо, вы не находите? Но большинство документаЦИР1, с которой приходится работать специалистам в области авто матизации процессов тестирования, выглядит именно так. На этих примерах хочется показать, что даже имея документацию из второго
24
Глава 1. Основы автоматизации
примера, вы все равно должны представлять себе уровень детализа ции, характерный для первого примера. Причина этого в том, что ваш скрипт должен будет выполнить КАЖДОЕ из действий, указанных в первом примере. Имея дело с документацией из второго примера, очень легко упустить из виду некоторые комбинации.
Из чего же, из чего же, из чего же сделана наша автоматизация Программная часть процесса автоматизации тестирования состоит из трех важных компонентов: • Библиотека функций (function library) — представляет собой на бор функций (пользовательских функций, о которых более под робно говорится в главе 8), используемых скриптами. Основным критерием при ее создангит является дублирующая функциональ ность. Этим термином можно назвать любую функцрюнальность програхммного продукта, которая встречается больше чем в одном скрипте. Типичным ее примером будет являться функция автори зации пользователя. Эта функциональность будет встречаться прак тически во всех скриптах. Прежде чем пользователь что-то смо жет сделать, он должен быть авторизирован, не так ли? • Библиотека объектов (object repository) — представляет собой опи сание всех графических объектов програмлшого продукта. Прежде чем любое из предоставленных на рынке средств автоматизации процессов тестирования сможет работать с каким-либо элемен том графического интерфейса пользователя, этот элемент должен быть описан в соответствующем формате и сохранен в специаль ном файле. Более детально о библиотеке объектов мы поговорим в следующей главе. • Библиотека скриптов (script library) — представляет собой набор скриптов, выполняющих задачи автоматического тестирования программного продукта. По сути, эта часть автоматизации явля ется «рабочим коньком» всего процесса. Помимо программной части, для автоматизации процессов тестиро вания нужны также документация (описание инфраструктуры, мат рицы исполнения и т. д.) и набор данных для автоматического тес тирования. В этот набор должны входить ожидаемые возвращаемые значения, данные, вводимые при исполнении тестов, и т. п.
Из чего же, из чего же, из чего же сделана наша автоматизация
25
Напоследок приведем два формальных определения: Скрипт — это логически законченная часть кода, сохраненная в от дельном файле и являюи];аяся программной реализацией определен ного тест-кейса. Ижрраструктура — это набор элементов автоматизации, обеспечи вающий стабильную и оптимизированную работу библиотеки скрип тов, при этом не являющийся частью программной реализации опре деленного тест-кейса. Инфраструктура включает в себя библиотеку функций, библиотеку объектов и набор данных, необходимых для проведения автоматического тестирования.
Глава 2 Record/Playback
в этой главе поговорим о таком незаменимом в начале работы по автоматизации элементе, как функциональность Record/Playback. Как можно догадаться из названия, эта функциональность позволя ет средству автоматизации тестирования программного обеспечения работать в режиме видеомагнитофона. Включаете Запись (Record), выполняете какие-то действия, останавливаете запись, включаете Проигрывание (Playback) и видите, как на экране эти самые действия повторяются с точностью до последнего движения мышью. Не надо впадать в эйфорию — серьезную автоматизацию таким способом создать нельзя. Однако использовать этот прием в качестве приме ра, что называется, сам Бог велел. Учитывая специфику конкретных продуктов, каждый из них будет рассмотрен по очереди, но вначале следует сказать, что же у них имеется общего. Итак, каждый продукт имеет средство опознавания объектов, библиотеку объектов и среду выполнения. Прежде чем уточнять детали, давайте сделаем небольшое отступление.
Как устроена автоматизация Думаю, ни для кого из читающих эту книгу не окажется новостью то, что все приложения, работающие в среде Windows, должны регу лярно посылать ей сообщения о своей работе. Существует множест во стандартных библиотек (MFC, JavaSwing PI Т. Д.), зависящих от языка, использованного для написания графического интерфейса пользователя, и ответственных за обработку сообщений пользовате ля и корректную работу приложения в среде Windows с использова нием Win32API. Именно на этой основе и построена архитектура автоматизации как таковая. Зная класс объекта и тип посылаемых ему сообщений, можно заставить его делать все, что тебе захочется.
27
WinRunner
не говоря уже о таких вещах, как симуляция активности клавиатуры или мыши с использованием все тех же псевдосообщений. Собственно средство опознавания объектов — это утилита распозна вания класса объекта и его свойств. Библиотека объектов — это ме сто, где полученная информация будет храниться в специфическом формате, а среда выполнения — это графическая оболочка, которая позволяет модифицировать и исполнять скрипты автоматизации. На этом закончим теоретический разговор и перейдем к конкрет ным примерам. Для большей наглядности рассмотрим ситуацию, ко гда в тест-приложении необходимо «записать» выбор размера пиц цы и трех ее начинок, после чего нажать кнопку подсчета стоимости.
Pizza Туре (^•- Large [$7.00] С Medium [$6.00] С Small [$5.00]
Toppings fyf Pepperony [$2.00] l< Mushrooms [$1.50] Г? Meat [$2.50]
WinRunner Выполнение записи L 2. 3. 4. 5.
Запустите WinRunner. Откройте первую страницу тест-приложения. Выберите в меню WinRunner опцию Fi'le • New. Сохраните файл как MyFirstWinRunnerFi'le (Fi4e • Save As). На панели управления WinRunner нажмите на кнопку Запись.
6. Выполните заданные действия. 7. На панели управления WinRunner нажмите на кнопку Стоп.
28
Глава 2. Record/Playback
*i* WmRishn^r ' (G:\eooks\A»itomatJon\Saipts\Wir«««M«rV'«yftf«tWtoRtt^
xr ^ y F J T ^ 'Г j ^ ^ ^ ^j;,^^: 4 « #^isi« ^^iIt?. [stop Recording]
Поздравляю! Вы только что записали свой первый скрипт. Давайте посмотрим, что у нас получилось.
Среда выполнения Среда выполнения выглядит следующим образом. ^t^ WinRunner - [6:\8ool«\Aiitemation\Scripfce\VftnRw»er\Mv*lr«tV«nR«weff М 0 fibp Ed* Create Run Ddbug Tods Settfrigy Viftn^
r 3
r p
N r г
# Р.7.-ГД е-ГОЧД'ТЛу ГЗ^'Й 5et_wandow ("V i г г а O r d e r i ng P s g e " , ' , ) ; b u t t o n s e t ("•CVP«"/0W) ; b u t t o n s e t ("p;?pperoY;y",ON) ; b u t t o n s e t ("mushrooK!3",CW) ; b u t t o n s e t {"we?«c-",ON) ; button_pres3("C«lculat^ Ordec");
To, ЧТО ВЫ видите на экране, является программным выражением предпринятых ранее действий. Не будем описывать здесь каждую из функций — это будет сделано в следующей главе. Вместо этого об ратите внимание на сам файл. В том виде, в котором он существует сейчас, — это готовый для ис rest Propei^tiesH полнения скрипт. Скрипты в 6<№«Ы j Descwptfort j Pwanwbs j Ad*jhe | CurentTesit j Яш | WinRunner бывают двух типов: скрипты и компилируемые мо дули. Компилируемые модули, iocaitott как уже говорилось в предыду Jivinnich 1 щей главе, являются строитель ным материалом для библио теки функций. Для того чтобы JMainTe$l 2I сделать из скрипта компили ^ш\»т JCgngdModji^^^^^^^^^l руемый модуль, необходимо поменять его свойство Test Туре - ', . (Fi'le • Test Properties) на Com piled Module. Затем его нужно скомпилировать (нажать на j jCaiwa } •A<:>p:t' { \Ий!> j ^ •'. 1 .^^_.ж... кнопку Запуск).
29
WinRunner
Но пока что нам это не нужно. Итак, скрипт готов к употреблению! Все, что нужно сделать дальше, — это нажать на кнопку Запуск i£.. Посмотрите, как можно тестировать приложение без вмешательства человека.
Библиотека объектов Ну как? Здорово, правда? Чего вы еще не знаете, так это что WinRunner сохранил еще один файл — библиотеку объектов, или GUIфайл. В этом файле хранятся описания объектов, с которыми только что были выполртены действия. Этот файл сохранен там же, где и скрипт, как файл с расширением *.6UI. Просмотреть его содержимое из среды выполнения можно следующим образом: Tools • GUI Map Editor, a сохраршть его со своим именем можно, выбрав Fi'le • Save As в открывшемся окне. Для того чтобы файл стал видимым для скрипта, в его начало нужно добавить следующую строчку кода: GUIJoddC'filename");, где filename — это имя GUI-файла.
.MM
^ШЯМарЙ1»0«^1 fite
€«к
« e w Opfefcwfw
Took
Help
\«.^ftdCHS*^fefett« ^
"Pizza Ordering Page"
\-m
"Calculate Order"
}^Ш
meat
Shew
W
8Ьо»Р!НЗ'!йбЫШ*Ы|{й»
zi
1
30
Глава 2. Record/Playback
Но так действовать нужно только через графический интерфейс. Сам файл можно открыть в обычном текстовом редакторе, и выгля деть он будет следующим образом: "Browser Main Window_r': { class: window, MSW^class: browser_main_window, NSTitle: "Browser Main Window", location: 1 } { ltree_state: open } "Pizza Ordering Page": { class: window, MSW^class: html__frame, html^name: "Pizza Ordering Page" } { ltree_^state: open } "Pizza Ordering Page"."Calculate Order": { class: push__button. MSW^^class: html__push_button, html__name: "Calculate Order" } "Pizza Ordering Page".meat: { class: check^button. MSW class: htnil__check_button, html^name: meat, part_value: on } "Pizza Ordering Page".mushrooms: { class: check^button, MSW^class: html__check__button, html__name: mushrooms,"" part~value: on } "Pizza Ordering Page".name: { class: edit, MSW^class: html__edit, }html^name: name
31
WinRunner
"Pizza Ordering Page".pepperony; { class: check_button, MSWclass: htmlcheckbutton. html_name: pepperony, partvalue: on } "Pizza Ordering Page".type: {
class: radio_button, MSW_class: html_radio_button, html^name: type, part^value: Large }
Средство опознавания объектов Для тех случаев, когда вы пишете свои функции и хотите просмот реть описание конкретного объекта, существует средство опознава ния объектов WinRunner — GUI Spy. Его можно вызвать следующим образом: Tools • GUI Spy. Чтобы получить информацию об объекте, просто нажмите кнопку Spy, наведите курсор на объект и нажмите Ctrl+F3! Нужное описание у вас перед глазами. Его можно скопиро вать в буфер обмена, нажав на кнопку Сору.
jPizza Ordering Page
"^ША^рАЬМфи^]' 'МШШЛш. class
V^tufr
wmdow
MSW.class htfnl_ffame html.name
Pizza Ordering Page
1^ )Щ)^Щжт "''\ ^-<^. Ш ^ у - ^ .^s^H^-^-^^f"^!
32
Глава 2. Record/Playback
SilkTest Библиотека объектов 1. Запустите SilkTest. 2. Откройте первую страницу тест-приложения. 3. Выберите в меню SilkTest команду File • New • 4Test Include file. 4. Сохраните его как MyFirstlncFile.inc. 5. Выберите в меню SilkTest команду Record • Window declarations.
M .r?" C^fSfef»,
jlPizza Ordering Page
P
Friar teat
j
Г
W ^ W P I D , fio
«1 @(543,453)
^AMtw deci^stior» {Pw*$ Ct
HtiTiiHedding HlmlHeading HtmlRadioList HtmlCheckBox HtrrCheckBox
PizzaTypel Toppings Pi2zaTvpe2 Pepperony200 Mu$hrooms150
Pizza Type Toppii^gs Pizza TypeWI Pepperony 42 OO^Ittl Mushro.Dm$ ?$1 50?|»2
Jjj
6. Наведите курсор мыши на первую страницу тест-приложения. 7. Нажмите Ctrl+Alt. 8. Нажмите кнопку ?^$ioedJt« . SilkTest должен выглядеть следующи1М образом.
Ы Э window BrowserChild PizzaOrderingPage • tag "Pizza Ordering Page" -^ parent Browser (S HtmlHeading PizzaTypel О HtmlHeading Toppings (Э HtmlRadioList PizzaType2 a HtmlCheckBox Pepperony200 Ш HtmlCheckBox MushroomslSO О HtmlCheckBox Meat250 Э HtmlPushButton CalculateOrder 03 HtmlPushButton Refresh OHtmlTable HtmlTablel SHtmllMage Calc IS HtmlText VebAdmin Q Htmllink SomeoneSomesiteCom
33
Silkiest
Поздравляю! Вы только что сохранили свою первую библиотеку объектов SilkTest. Для того чтобы можно было использовать объек ты этой библрготеки, вы должны включить в ваш скрипт следующий код: use "myfirstincfile.inc". Это файл также можно открыть в лю бом текстовом редакторе.
Выполнение записи 1. 2. 3. 4. 5. 6.
Запустите SilkTest. Откройте первую страницу тест-приложения. Выберите в меню SilkTest комарщу File • New • 4Test script. Сохраните его как MyFirstSilkFile.t. Выберите в меню SilkTest команду Record • Testcase. Нажмите кнопку Start Recording. ^•
ReeoMt T e s t c ^ i i i i i l l
M
3
Щопе) l««tce*6tod
1 ^
•
*
^
Canc«) 1
7. Выполните заданные действия. 8. Нажмите на кнопку Done. шш^ш^ш^ш Te
^^^^П Rre^
to vfif#tw^PW
^^^.^.j^^iy*^^. I
^S'gf» I
9. Нажмите на кнопку p4^Wlo Mi» . Давайте посмотрим, что же у нас получилось.
34
Глава 2. Record/Playback
Среда выполнения Среда выполнения выглядит следующим образом. SSittcTest fife Edit Outline Record ftufs Options Window Help
т4Тев1 Scr4)t> ftecorrfiftsi* Q testcase Testl () appstate none Q recording * BrowserPage.SetActive () » BrowserPage.HtJiilRadioListC"PizzaTypeI#1**) .Select ("Large [$7.00]") ^ BrowserPage, Ht ml CheckBox (" Pepper ony ?$2.00?|#1'*). Check () * BrowserPage.HtmlCheckBox("Mushrooms ?$1.50?!#2").Check () * BrowserPage. HtmlCheckBox( "Meat ?$2.50?i#3''). Check () « BrowserPage.HtmlPushButton("Refreshli#l").Click ()
To, что вы видите на экране, является программным выражением предпринятых ранее действий. Не будем описывать здесь каждую из функц1п1 — это будет сделано в следующей главе. Вместо этого об ратите внимание на сам файл. В том виде, в котором он существует сейчас, — это готовый для исполнения скрипт. Основные фар1лы в SilkTest бывают двух типов: скрипты (*.t) и файлы библиотеки объ ектов (*.1пс). Скрипты могут служить как для стандартного исполь зования, так и для использования в качестве компилируемых мо дулей. Компилируемые модули, как уже говорилось в предыдущей главе, являются строительным матерршлом для библиотеки функ ций. Для того чтобы функции, определенные в библиотечные фай лы, были доступны любому скрипту, эти скрипты должны иметь следующую строку кода: use "filename.inc". Но пока нам это не нуж но. Хочу также отметить, что все выполняемые строки кода должны находиться внутри блока testcase. Один скрршт может иметь множе ство тест-кейсов, которые будут исполняться по очереди. (Для того чтобы выполнить лишь один тест-кейс, необходимо нажать кнопку Выполнить тест-кейс []Ц и выбрать нужное значение из списка дос тупных тест-кейсов.) Итак, скрипт готов к употреблению! Все, что для этого нужно сделать, — нажать на кнопку Запуск ДЦ.
Средство опознавания объектов Когда вы пишете свои функции и хотите просмотреть описание кон кретного объекта, существует средство опознавания SilkTest — Window Identifiers. Его можно вызвать следующим образом: Record • Window
35
Rational Robot
Identifiers. Чтобы получить информацию об объекте, просто наведи те на него курсор и нажмите Ctrt+Alt! Нужное описание у вас перед глазами. Его можно скопировать в файл, нажав на кнопку Paste to Editor. Record VWndow ТйезпЛяШШ
fЩф^1фemm' BrowserPage HtmPushBu«on("Calculate Ofderltti"]
Pa^
Сои>toOipboafd
СЫе
Rational Robot Выполнение записи 1. 2. 3. 4. 5.
Запустите Rational Robot. Откройте первую страницу тест-приложения. Выберите в хменю Rational Robot команду File • New • Script. Введите в появившемся окне имя MyFirstRationalRobotFUe. На панели управления Rational Robot нажмите кнопку GUI.
шшшшвшшвт 6. Введите в появившемся окне имя MyFirstRationalRobotFUe. 7. Выполните заданные действия. 8. На панелр! управления Rational Robot нажмите кнопку Stop Recor ding.
36
Глава 2. Record/Playback
Среда выполнения среда выполнения выглядит следующим образом. Г^ t *
«р» B«w
V*«J4W И *
^«^^
<#%jg8§V3fe'
OS'H:"ff?T;P'jy!?y'fiff!? 1
0 Verification Points
1 LociO^ Function pristctvpes
^ ^ ^ i ^ ^ ^ W ? - m Л ^.
Option Explicit Sub Main Din Result Й5 Integer 'IrtU.inlly Riiieat" PtishBiitton Click, "HTMLText=Calculate Order" Window SetContext, "Class»=Shell_TrayWnd", "" TabControl Click, "0bjectIndex-1;\;IteriIndex-7",
End Sub
To, что вы видите на экране, является программным выражением предпринятых ранее действий. Не будем описывать здесь каждую функцию — это будет сделано в следующей главе. Вместо этого об ратите внимание на сам файл. В том виде, в котором он существу ет сейчас, — это готовый для исполнения скрипт. Файлы в Rational Robot бывают трех типов: скрипты (*.гес), файлы-заголовки (*.sbh) и библиотечные файлы (*.sbl). Библиотечные файлы (компилируе мые модули), как уже говорилось в предыдущей главе, являются строительным материалом для библиотеки функций. Для того что бы функции, определенные в библиотечные файлы, были доступны любому скрипту, они должны быть «объявлены» в файле заголовкГ (как и глобальные переменные), а затем скомпилированы с исполь зованием функции File • Compile. Но пока нам это не нужно. Следует отметить, что все выполняемые строки кода должны находиться внутри процедуры Main. Итак, скрипт готов к употреблению! Просто нажмите кнопку Запуск ^ . Посмот рите, как можно тестировать приложение без вмешательства чело века.
37
Rational Robot
Библиотека объектов Rational Robot, единственный из «Большой тройки», не сохраняет объ екты в отдельный файл, а пользуется их описанием в параметрах, передаваемых функциям в скриптах исполнения.
Средство опознавания объектов Средство опознавания объектов Rational Robot — Inspector. Его можно вызвать следующим образом: Tools • Inspector. Информация обо всех объектах, находящихся на Рабочем столе, у вас перед глазами. ^мм:
рАр е л -vjw twrf^ *ф
nSSBS!
"3
ass
EditBoK,0b|ecttndex-1 Rebaf,0biecrindey=1
Toolbaf,0b|ec»lndex«1 Unknown Combo8 OX.0 biecll ndex-1
J
ComboBox Obtectlndex«2 ComboEdit8ox 0b|ecrtndex*2 Toolb«,0b|ectindex»2 ComboBox,0b|ecHndex»3 Tooibaf,0b|ecHndex-3 ComboBox Obiecllndex-4 ComboEd«Box.Ob)ecllndex=4 Toolb«ID-40960 EdrtBox,0b(ectlndex>2 Toolbar Ob|ecHndex»5 Edrt8ox,0b(ecHndex-3 S tatusB ar.O biecH ndex-l Progfe$$Bar,0b|ecHndex-1 v
Genenc.Ob|ecHndex«l Genefic.0b(ecHndex-2
\/п1кт£ж/(хЫ>0Е.
Zl
Serve Window
r. Window,CaptKjn»Pi22a Ordering Page - Microsoft Intern '-- Properbe* C«&ee«jKViWtWif
W i d t h . 180 00000 Height-24 00000 Visible-True Enabled-True Left--32000 00000 T o p - - 3 2 0 0 0 00000 Caption - Pizza Oidenng Page - Microsoft interr
С1с!(«Й«ю&ШНЕМ))
WndowState - Mrwmzed WndowStHe - Overlapped BorderStyle - Resizeable SystemMenu - True
f!j0»»«hJ2J5Jrt^
a^iM*Ai
MmButton • True MaxButton - True
-^
J
iJ
i^lEb«i^$l>)>f)«iWr«4^«4)#4it^
г^тг'^_.4
Глава 3 Язык скриптов
в этой главе поговорим о таком элементе программирования, как язык скриптов. Каким бы хорошим ни был программный продукт автоматизации процессов тестрфования, какую бы замечательную функциональность он не предоставлял — именно язык скриптов яв ляется основным механизмом хорошего автоматизированного теста. Что же представляет собой этот язык? По сути, это программный язык, позволяющий настраивать и оптимизировать скрипты. Это та база, без которой не может существовать ни один программный про дукт автоматизации процессов тестирования. Будучи скомпилиро ванным в маип1нный код, язык скриптов заставляет тестируемую программу поверить в то, что пользователь выполняет определен ные действия, и, соответственно, адекватно (или не совсем) реагиро вать. Языки скриптов в зависимости от архитектуры, выбранной постав щиком программного продукта автоматизации процессов тестирова ния, могут быть самыми разными. Язык SilkTest (4test), являющийся, на мой взгляд, самым лучшим из существующих в данный момент, имеет объектно-ориентированную архитектуру. Язык WinRunner (TSL — Test Scripting Language) — типичный процедурный язык. Язык Rational Robot (SQABasic) является модифицированной версией язы ка Visual Basic. Так или иначе, язык скриптов должен соответство вать ряду требований, о которых и поговорим далее.
Переменные Переменные представляют собой участки памяти (ПЗУ), хранящие определенную информацию. В зависимости от типа хранимой ин формации переменные могут принадлежать к различным типам.
39
Переменные
Наиболее распространенными типами переменных являются строки (наборы символов), целые числа, числа с плавающей запятой и ло гические переменные.
TSL (WinRunner) TSL по своей структуре является языком с необязательным указа нием типа переменной. Такая архитектура языка определяет два воз можных вида работы с переменными: прямое и непрямое определе ние. Во втором случае происходит следующее: искомая переменная инициализируется непосредственно при использовании. Тип пере менной будет определен при ее инициализации по типу передавае мого значения (это может быть число или строка). Пример. Следующая строка кода инициализирует переменную user_report как строку со значением «Попытка № 5»: user_report = "Попытка №" & 5;
Следует отметить, что значение по умолчанию переменной, опреде ленной непрямым способом, равняется <о> (null). То есть если при первом использовании такая переменная не будет стоять по левую сторону от знака равенства (или значение не будет ей передано ка ким-либо иным путем), то тип переменной определяется как «стро ка» со значением, равным «» (пустая строка). При прямом определении указываются класс переменной (табл. 3.1), ее имя и инициализирующее выражение (последнее является жела тельным, но не обязательным). То есть определение имеет следую щую форму: class variable [ = initexpression ] :
Таблица 3 . 1 . Классы переменных Класс
Видимость
Срок жизни
Определяется
Auto
Локальная
До конца выполнения функции
Только в функциях
Static
Локальная
До конца выполнения скрипта
В функциях, скриптах или компилируемых модулях
РиЫ i с
Глобальная
До конца выполнения скрипта
В тестах или компили руемых модулях
Extern
Глобальная
До конца выполнения скрипта
В функциях, скриптах или компилируемых модулях
40
Глава 3. Язык скриптов
Тип переменной, как при определении непрямым способом, будет определен по типу передаваемого значения в инициализирующем выражении. Класс переменной определяет ее «видимость» для остального кода и очерчивает рамки ее использования. Рассмотрим классы подробнее: • auto. Переменная этого класса может быть определена только в функции пользователя и является локальной переменной этой функции (ее видно только из этой функциР!). Значение перемен ной уничтожается после возвращения управления вызвавшему скрипту/функции. • static. Переменная этого класса может быть определена в функ ции пользователя, скрипте или компилируемом модуле и являет ся их локальной переменной (ее видно только из этих функ ции/скрипта/модуля). Значение переменной уничтожается после прекращения выполнения скрипта. • public. Переменная этого класса может быть определена только в скргтте или компилируемом модуле и является глобальной пе ременной (ее видно из любых функции/скрипта/модуля). Значе ние переменной уничтожается после прекращения выполнения скрипта. • extern. Переменная этого класса может быть определена в функ ции пользователя, скрипте или компилируемом модуле и является указателем на переменную public, определенную вне данных функ ции/скрипта/модуля. Пример. Следующая строка кода инициализирует переменную user_report как строку со значенртем «Попытка № 5» и делает ее видимой для всех функций/скриптов/модулей: public user_report = "Попытка №5":
TSL также поддерживает определение констант. Константа — это переменная, значение которой не может быть впоследствии измене но. Синтаксис объявления константы является следующим: [ class ] const name [ = expression ]: Здесь class может быть только public или static.
Пример. Следующая строка кода инициализирует переменную user_report как строчную константу со значением «Попытка № 5». public const userreport = "Попытка Ife5":
41
Переменные
4TEST (SilkTest) Язык скриптов 4test по своей структуре является языком с обяза тельным указанием типа переменной. Подобная архитектура языка подразумевает четкое определение типа определяемой переменной. Синтаксис определения переменной следующий: [ scope ] [ share ] data-type variable-id [ = ехрг ]
где scope — класс переменной. Может быть public (видимой для всех скриптов) или private (видимой только внутри определяющего скрип та); share — флаг определения доступности переменной несколькими процессами одновременно. Может быть share, если доступ разрешен, и null — если нет. Доступ контролируется оператором access; data type — тип данных (табл. 3.2); variable-id — имя переменной; ехрг — иницР1ализирующее выражение. Таблица 3 . 2 . Типы данных Тип данных
Описание
Граничные значения
INTEGER
Целое число
Минимальное: - 2 147 483 648
REAL
Дробь
Машинозависимо. Обычно занимает от 2,23Е-308до 1,79Е308, положительное и отрицательное
NUMBER
Число
Объединение INTEGER и REAL
DATE
Дата
Минимальное: -4713.01.01 (отрицательные значения для дат до нашей эры (до н. э.))
Максимальное: 2 147 483 647
Максимальное: 19999.12.31 (положительные значения для дат нашей эры (н. э.)) TIME
Время
Минимальное: 00:00:00.000000 Максимальное: 23:59:59.999999
STRING
Строка
Минимальное: Нет символов (пустая строка) Максимальное: 16 383 символов
STRING
Строка-кон-
MnnHManbYioe: Нуль символов (пустая строка)
constant
станта
Максимальное: 4096 символов
BOOLEAN
Логическая переменная
TRUE или FALSE
Identi f i e r s
Указатель
Минимальное: 1 символ Максимальное: 2048 символов
42
Глава 3. Язык скриптов
Пример. Следующая строка кода инициализирует переменную iTestNum как целочисленную переменную со значением О и делает ее доступной для нескольких процессов одновременно: public share integer iTestNum = О
Пример. Следующая строка кода инициализирует переменную user_ report как строку со значением «Попытка № 5», делает ее види мой для всех скриптов и недоступной более чем одному потоку: public s t r i n g userreport = "Попытка №5"
4test также поддерживает определение констант. Синтаксис объяв ления константы: [scope] const [data-type] const-name = expr
где scope — класс переменной. Может быть public (видимой для всех скриптов) или private (видимой только внутри определяющего скрип та); data-type - тип данных (INTEGER, REAL, STRING или BOOLEAN); constname — имя константы; expr ~ инициализирующее выражение. Пример. Следующая строка кода инициализирует переменную user_ report как строчную константу со значением «Попытка № 5»: public const s t r i n g user_report = "Попытка №5"
SQABasic (Robot) Язык скриптов SQABasic по своей структуре является языком с обя зательным указанием типа переменной. Подобная архитектура язы ка подразумевает четкое определение типа переменной. Синтаксис определения переменной является следующим: Dim [ Shared ] variableName [As type]
где Shared — флаг определения доступности переменной нескольки ми процессами одновременно. Shared — если доступ разрешен, null — если нет. Доступ контролируется оператором access; variableName — имя переменной; type — тип данных (см. табл. 3.3). Пример. Следующая строка кода инициализирует переменную counter как целочисленную: Dim counter As Integer Таблица 3.3. Типы данных Тип данных
Описание
Граничные значения
Integer
Короткое целое число
Минимальное: -32 768 Максимальное: 32 767
43
Массивы данных
Тип данных
Описание
Граничные значения
Long
Длинное целое число
Минимальное: - 2 147 483 648 Максимальное: 2 147 483 647
Single
Короткая дробь
От -3,402Е38 до -1,401Е-45 — отрица тельные значения От 1,401Е-45 до 3,402Е38 — положи тельные значения
Double
Длинная дробь
От -1,797Е308 до -4,94Е-324 - отри цательные значения От 4,94Е-324 до 1,797Е308 — положи тельные значения
Currency
Время
Минимальное: -922 337 203 685 477.5808 Максимальное: 922 337 203 685 477,5807
STRING
Строка
Минимальное: Нет символов (пустая строка) Максимальное: 32 767 символов
STRING
Строка фиксирован ной длины
Минимальное: 1 символ Максимальное: 32 767 символов
SQABasic также поддерживает 01тределенр1е констант. Синтаксис объ явления константы является следующим: [Global] Const constantName [As type ]= expression
где Global — флаг определения глобальности переменной; type — тип данных (Number или String); constantName — имя константы; expres sion — инициализирующее выражение. Пример. Следующая строка кода инициализирует переменную user_ report как строчную константу со значением «Попытка № 5»: Const user_report As String = "Попытка IfeS"
Массивы данных Массивы данных представляют собой набор переменных, упорядо ченных в единую систему. Целочисленный массив из 10 элементов представляет собой 10 переменных целого типа, имеющих одно и то же имя, но различающихся порядковым номером. Массивы могут быть как одномерными, так и многомерными. Простейшим приме-
44
Глава 3. Язык скриптов
ром многомерного массива является таблица. Чтобы получить зна чение ячейки, нужно знать ее точное расположение, то есть номер столбца (измерение № 1) и номер ряда (измерение № 2). Еще одним типом массива является список (List), но поскольку в контексте дан ной книги он встречается только в SilkTest, мы более детально пого ворим о нем в рамках обсуждения последнего.
TSL (WinRunner) TSL поддерживает два типа массивов: статический и динамический. Динамический массив не требует обязательного объявленргя количе ства его элементов и имеет следующий синтаксис объявления: class array^name [ =init_expression ]
где cl ass — это класс массива, такой же, как и у переменных (см. пре дыдущий раздел); init_expression — инициализатор массива. Обращение к элементам такого массива осуществляется посредством указания имени массива и порядкового номера элемента (первый эле мент имеет индекс 0): temp_var = МуАггау[1]
Статический массив представляет собой массив фиксированной дли ны и имеет следующую форму: static guijtem ={ "class''="push_button". "label "="0К'\ "X_class"="XmPushButtonGadget".
"X"=10. "Y"=60 };
Обращение к элементам такого массива осуществляется посредством указания имени массива и текстового ключа элемента: temp^var = gui^item ["label" ]
4TEST (SilkTest) 4test поддерживает только жестко определенные массивы с воз можностью изменения количества элементов (см. раздел «Функ ции работы с массивами»). Массивы могут быть как одномерны ми, так и многомерными. Объявление массива имеет следующий синтаксис:
Массивы данных
45
ARRAY [dimension] [, dimension ] . . . OF data-type array-id
где dimension — имя массива; data-type — тип данных массива (см. пре дыдущий раздел); array-id — имя массива. Обращение к элементам такого массива осуществляется посредст вом указания имени массива и порядкового номера элемента (пер вый элемент имеет индекс 1): ARRAY [10] [100] OF INTEGER MyArray temp_var = MyArray[l,99] tempvar = MyArray[l][99]
Частным случаем массива является список (List). Список может со стоять из данных любого типа и отличается от массива тем, что гра ницы списка не должны быть определены при его объявленрп!. Объ явления массива имеют следующий синтаксис: LIST [ OF data-type ] l i s t - i d [= elements]
где data-type — тип данных массива (см. предыдущий раздел); 1istid — имя списка; elements ~ начальные элементы списка. Обрандение к элементам такого списка осуществляется посредством указания имени списка и порядкового номера элемента (первый эле мент ршеет индекс 1): LIST OF ANYTYPE NewList ={...} "a" sSomeString "cde" i +1 tempvar = NewList[3] #возвращает "cde"
SQABasic (Robot) SQABasic поддерживает как жестко определенные массивы с возмож ностью изменять в дальнейшем количество элементов (см. раздел «Функции работы с массивами»), так и динамические массивы. Мас сивы могут быть как одномерными, так и многомерными. Объявления массива имеют следующий синтаксис: Dim Аггаупате (Diml. Dim2....) as data-type
где Array^name — имя массива; Diml, Dim2... — измерения массива; data type — тип данных массива (см. предыдущий раздел). Обращение к элементам такого массива осуществляется посредством указания имени массива и порядкового номера элемента (первый элемент имеет индекс 0):
46
Глава 3. Язык скриптов
Dim МуАггау (10,100) as Integer temp_var = МуАггау[1,99]
Операторы Операторы представляют собой элементы языка, позволяющие про изводить действия над другими элементами языка. Наиболее рас пространенными являются операторы сложения, вычитания, умно жения, деления, деления нацело и конкатенации (объединения) строк. Операторы, позволяющие производить бинарные действия, в кон тексте программных продуктов автоматизации процессов тестирова ния не являются актуальными.
TSL (WinRunner) TSL поддерживает следующие операторы: Оператор
Значение
+ *
Сложение
/
Деление
Вычитание Умножение
%
Деление нацело (остаток от деления) или * *
Возведение в степень
++
Увеличение на 1
--
Уменьшение на 1
4TEST (SilkTest) 4test поддерживает следующие операторы: Оператор
Значение
+
Сложение
-
Вычитание
•
Умножение
/ X
Деление Деление нацело (остаток от деления)
-к-к
Возведение в степень
-н-
Увеличение на 1
--
Уменьшение на 1
Логические операторы
47
SQABasic (Robot) SQABasic поддерживает следующие операторы: Оператор
Значение
+
Сложение
•-
Вычитание
•
Умножение
/
Деление
Mod
Деление нацело (остаток от деления)
А.
Возведение в степень
Логические операторы Логические операторы, как следует из их названия, позволяют про изводить действия над логР1ческими переменными. По большому сче ту, это операции постановки условий. Наиболее распространенны ми являются логические операторы И, ИЛИ и НЕ. Выражения, стоящие справа и слева от оператора И, должны быть истинными. Из выраже ний, стоящих справа и слева от оператора ИЛИ, хотя бы одно должно быть истинными. Выражение, следующее после оператора НЕ, долж но иметь значение, противоположное значению предшествующего выражения: НЕ ИСТИНА является ЛОЖЬЮ.
TSL (WinRunner) TSL поддерживает следующие логические операторы: Оператор
Значение
&&
И
II
ИЛИ
J
н^
4TEST (Silkiest) 4test поддерживает следующие логические операторы: Оператор
Значение
&&
И
II
ИЛИ
!
НЕ
48
Глава 3. Язык с к р и п т о в
SQABasic (Robot) SQABasic поддерживает следующие логические операторы: Оператор
Значение
Оператор
Значение
And
И
Хог
Бинарное И
Or Not
ИЛИ
Eqv
Бинарное ИЛИ
НЕ
Imp
Бинарное НЕ
Операторы сравнения Операторы сравнения, как следует из их названия, позволяют срав нивать элементы языка между собой. Наиболее распространенными операторами сравнения являются «равно», «не равно», «больше Р1ЛИ равно», «меньше или равно», «больше» и «меньше». В подавляюш;ем большинстве случаев они дополняют условные операторы или опе раторы цикла, зачастую вместе с логическими операторамР!.
TSL (WinRunner) TSL поддерживает следующие операторы сравнения: Оператор
Значение
Оператор
Значение
> >= <
Больше
<= == !=
Меньше или равно
Больше или равно Меньше
Равно Не равно
4TEST (SilkTest) 4test поддерживает следующие операторы сравнения: Оператор
Значение
Оператор
Значение
>
Больше
<=
Меньше или равно
>=s
Больше или равно Меньше
== !=
Равно
<
Не равно
SQABasic (Robot) SQABasic поддерживает следующие операторы сравнения:
49
Условные операторы
Оператор
Значение
Оператор
Значение
>
Больше
Меньше или равно
>=
Больше или равно
<= =
Равно
<
Меньше
о
Не равно
Условные операторы Условные операторы служат для разделения кода на части, исполне ние которых зависит от определенных условий. Существуют три ос новных типа условных операторов: IF, IF... ELSE и SWITCH. Условный оператор IF (Если) имеет следующую форму: IF логическое условие
код исполнения и служит для ограничения исполнения кода, содержащегося внутри него, событием, указанным в его начале. Условный оператор IF... ELSE (Если... иначе) имеет следующую форму: IF логическое условие код исполнения ELSE код исполнения
и служит для создания «вилки» в исполнении кода. Если событие, указанное в его начале, истинно, то выполняется та часть кода, кото рая находится внутри IF, в противном случае — та, которая находит ся внутри ELSE. Условный оператор SWITCH (Переключение) имеет следующую форму: SWITCH(пepeмeннaя) CASE значение!: код исполнения CASE значение2: код исполнения CASE значениеЗ: код исполнения DEFAULT: код исполнения по умолчанию
и служит для определения выполняемого кода в ситуации множест венных (больше двух) вариантов события.
TSL (WinRunner) TSL поддерживает оба условных оператора, IF... ELSE и SWITCH.
50
Глава 3. Язык скриптов
Условный оператор 1Р~. ELSE имеет следующий синтаксис: i f ( expression ) { statementl }[ else { statement2 }]
при этом оператор if может использоваться как с оператором else, так и без него. Пример. Следующий блок кода возвращает «Миллионер», если значение переменной Fortune больше 1 000 000, и «Пока не мил лионер» — в противном случае: if (Fortune>1000000 ) { return "Миллионер": }e1se
{ return "Пока не миллионер"; } Условный оператор SWITCH имеет следующий синтаксис: switch ( expression ) { case case^exprl: statement(s) case case_expr2: statement(s) case case exprn: statement(s) [ default: statement(s) ]
} Пример. Следующий блок кода возвращает «Левый», если значе ние переменной Party равно «Коммунист», «Правый» — если «Яблоко», и «Центрист» — если «Единая Россия». При этом зна чение по умолчанию будет «Беспартийный». Обратите внимание на использование операторов break в конце каждого блока case — оно обеспечивает единичность выбора: switch (Party) { case "Коммунист": return "Левый"; break; case "Яблоко":
Условные операторы
51
return "Правый"; break; case "Единая Россия": return "Центрист"; break; default: return "Беспартийный"; }
4TEST (SilkTest) 4test поддерживает оба условных оператора, IF^ ELSE и SWITCH. Условный оператор IF... ELSE имеет следующий синтаксис: i f boolean-expr statement [else statement]
при этом оператор if может использоваться как с оператором else, так и без него. Пример. Следующий блок кода возвращает «Миллионер», если значение переменной Fortune больше 1 000 000, и «Пока не мил лионер» — в противном случае: i f (Fortune>1000000 ) return "Миллионер"е1$е
return "Пока не миллионер"
Условный оператор SWITCH имеет следующий синтаксис: switch (ехрг) case case-value(s)
statement [ case case-value(s) statement ]... [ default
statement ] . . . Пример. Следующий блок кода возвращает «Левый», если значе ние переменной Party равно «Коммунист», «Правый» — если «Яблоко», и «Центрист» — если «Единая Россия». При этом зна чение по умолчанию будет «Беспартийный». Обратите внимание на использование операторов break в конце каждого блока case — оно обеспечивает единичность выбора: switch (Party) case "Коннунист": return "Левый" break
52
Глава 3. Язык скриптов
case "Яблоко": return "Правый" break case "Единая Россия": return "Центрист" break default: return "Беспартийный"
SQABasic (Robot) SQABasic поддерживает оба условных оператора, IF... ELSE и SWITCH. Условный оператор IF... ELSE имеет следующий синтаксис: I f condition Then statement^block [ El self expression Then statement^block]... [ Else statement_block ] End I f
при этом оператор i f может использоваться как с операторами el se и elseif, так и без них. Пример. Следующий блок кода возвращает «Миллионер», если значение переменной Fortune больше 1 000 000, и «Пока не мил лионер» — в противном случае: I f Fortune>1000000 Then FuncName = "Миллионер"Еие End I f
FuncName = "Пока не миллионер"
Условный оператор SWITCH имеет следующий синтаксис: Select Case testexpression [Case expressionlist [statement^block] ] [Case expressionlist [statementblock] ] [Case Else [statementblock] ] End Select
Пример. Следующий блок кода возвращает «Левый», если значе ние переменной Party равно «Коммунист», «Правый» — если «Яблоко», и «Центрист» — если «Единая Россия». При этом зна чение по умолчанию будет «Беспартийный»:
Операторы цикла
53
Select Case Party) Case "Коммунист": FuncName = "Левый" Case "Яблоко" FuncName = "Правый" Case "Единая Россия": FuncName = "Центрист" Case Else FuncName = "Беспартийный"
Операторы ци1сла Операторы цикла представляют собой конструкции, позволяющие по вторять одно и то же действие множество раз. Существуют два ос новных типа операторов цикла, FOR и WHILE. Оператор цикла FOR является численно задаваемым оператором, то есть количество прохождений цикла задается целым числом. Счет чик повторений сравнивается со значением определяющей перемен ной и увеличивается (уменьщается) на заданную величину с каж дым прохождением цикла: FOR (счетчик=начальное значение; счетчик<=(>=, и т . д . ) определяющая переменная; счетчик + заданная величина) код исполнения
Оператор цикла WHILE является логически задаваемым оператором. В отличие от оператора цикла FOR, оператор цикла WHILE будет ис полняться до тех пор, пока его логическое условие не будет выпол нено: WHILE (логическое условие) код исполнения Третий оператор цикла, DO.. WHILE, является логически задаваемым оператором. В отличие от оператора цикла WHILE, DO.. WHILE проверяет логическое условие в конце кода исполнения, а не в начале: DO
код исполнения WHILE (логическое условие)
TSL (WinRunner) TSL поддерживает все три оператора цикла: FOR, WHILE и DO.. WHILE.
54
Глава 3. Язык скриптов
Оператор цикла FOR имеет следующий синтаксис: fc ( [ expression! ] ; [ expression2 ] : [ expressions ] ; ) for {{ statement }
Пример. При начальном значении счетчика, равном О, следующий блок кода выводит ч^Попытка №» до тех пор, пока счетчик не при мет значение 6: for ( i-0; i<6; i-H+) { report msg("Попыткаfc"& i ); }
Оператор цикла WHILE имеет следующий синтаксис: while (expression) # while this is true { statement* perform this statement }
Пример. Следующий блок кода печатает 4:Попытка Ме^ до тех пор, пока не будет выведена строка «Попытка № 5»: while (i<6) { report_msg( "Попытка li" & i ): i++; }
Оператор цикла 00^ WHILE имеет следующий синтаксис: do { statement }while ( expression );
Пример. Следующий блок кода печатает «Попытка №» до тех пор, пока не будет выведена строка «Попытка № 5»: do {
report_msg("Попыткаfc"& i ); i++;
}while (i<5);
4TEST (SiikTest) 4test поддерживает только операторы цикла FOR и WHILE:
Операторы цикла
55
Оператор цикла FOR имеет следующий синтаксис: for ( [init-stmt] : [boolean-ехрг] ; [incr-stmt] ) statements
Пример. При начальном значении счетчика, равном О, следующий блок кода печатает «Попытка №» до тех пор, пока счетчик не ста новится равен 6: for ( l-'O; 1<б: l-H-)
Print ("Попыткаfc"+Str( 1) )
4test также поддерживает две вариации оператора цикла FOR. Первая: for numeric iterations: for loop-var » start-expr to end-expr [step step-expr] statement
Пример. Следующий блок кода печатает «Попытка №» до тех пор, пока счетчик не становится равен 6: for i»0 to 6 step 1
Print ("Попыткаfc"+Str( i) )
Вторая: for each: for each item in expr
statement
Пример. Следующий блок кода печатает каждое значение в мас сиве IsFruit: for each sFruit in IsFruit
Print (sFruit)
Оператор цикла WHILE имеет следующий синтаксис: while boolean-expr
statement
Пример. Следующий блок кода печатает «Попытка Х9» до тех пор, пока не будет напечатана строка «Попытка №5»: while (i<6) Print ("Попытка la" +Str{ i) ) i++
SQABasic (Robot) SQABasic поддерживает все три оператора цикла, FOR, WHILE и DO^WHILE. При этом в операторах цикла WHILE и DO.WHILE появляется оператор UNTIL. При использовании этого оператора цикл будет исполняться до тех пор, пока не наступит ситуация, описанная в логическом вы ражении оператора UNTIL.
56
Глава 3. Язык скриптов
Оператор цикла FOR имеет следующий синтаксис: For counter = start ТО end [STEP increment] [ statementblock ] [ Exit For ]
[ statementblock ] Next [ counter ]
Пример. При начальном значении счетчика, равном О, следующий блок кода печатает «Попытка Х»» до тех пор, пока счетчик не ста новится равен 6: For i=0 ТО 6 STEP 1 SQALogMessage sqaNone, " Попытка №" & Str$( j ) , "" Next i
Оператор цикла WHILE имеет следующий синтаксис: Do [ { While | Until } condition] [ statementblock ] [ Exit Do ] [ statementblock ] Loop
Пример. Следующий блок кода печатает «Попытка №» до тех пор, пока не будет напечатана строка «Попытка № 5»: Do While i<6
SQALogMessage sqaNone. " Попытка Ite" & Str$(j) , "" i++
Loop
Оператор цргкла DO.WHILE имеет следующий синтаксис: Do [ [ [ Loop [ {
statement_block ] Exit Do ] statement_block ] While I Until } condition]
Пример. Следующий блок кода печатает «Попытка №» до тех пор, пока Pie будет напечатана строка «Попытка №5»: Do
SQALogMessage sqaNone. " Попытка №" & Str$(j) . "" i-H-Loop Until i=5
Функции приведения типов Функции приведения типов являются встроенными функциями язы ка и позволяют трансформировать один тип данных в другой. Набор
функции приведения типов
57
предоставляемых функций напрямую зависит от предоставляемых конкретным языком типов данных.
TSL (WinRunner) TSL по своей структуре является языком с необязательным указа нием типа переменной. Подобная архитектура языка делает сущест вование функции! приведения типов невозможным.
4TEST (SJIkTest) 4test по своей структуре является языком с обязательным указа нием типа переменной. Подобная архитектура языка подразумевает четкое определение типа переменной. 4test предоставляет пользова телю следующие функции приведения типов. sNum = Str (nNum [. iWidth, iDec])
где sNum — переменная типа STRING, полученная путем приведения nNum; nNum — переменная типа NUMBER, содержащая цифровое представление символьного значения; 1 Width — длина возвращаемой строки (необя зательный параметр); iDec — количество цифр после запятой (не обязательный параметр). Функция приводит переменную типа NUMBER, содержащую цифровое представление символьного значения, в переменную типа STRING, со держащую соответствующее символьное значение. Пример. Следующая строка кода возвращает строку «-2.32»: sNum = Str (-2.321,4,2) nNum = Val (sToConvert)
где nNum — переменная типа NUMBER, полученная приведением sToConvert; sToConvert — переменная типа STRING, содержащая символьное пред ставление цифрового значения. Функция приводит переменную типа STRING, содержащую символь ное представление цифрового значения, в переменную типа NUMBER, содержащую соответствующее цифровое значение. Пример. Следующая строка кода приводит строку «2» к типу NUMBER со значением 2: nNum = Val ("2")
Хотелось бы также отметить наличие следующих двух функций, кото рые не полностью подпадают под определение «функции приведения типов», но при этом имеют довольно большое значение для работы.
58
Глава 3. Язык скриптов
Функция
Описание
iCode^Asc (sString)
Функция возвращает ASCII-код символа s S t r i n g
sChar = Chr ( i i n t )
Функция возвращает символ со значением ASCIIкода, равным i l n t
SQABasic (Robot) SQABasic по своей структуре является языком с обязательным ука занием типа переменной. Подобная архитектура языка подразуме вает четкое определение типа переменной. SQABasic предоставляет пользователю следующие функции приведения типов. sNum =* Str$( number )
где sNum — переменная типа STRING, полученная приведением nNum; number — переменная, содержащая цифровое представление символь ного значения. Функция приводит переменную, содержащую цифровое представле ние символьного значения, в переменную типа STRING, содержащую соответствующее символьное значение. Пример. Следующая строка кода возвращает строку «-2.321»: sNum = Str$ (-2.321) nNum * Va1( string! )
где nNum — цифровая переменная, полученная приведением sToConvert; string! — переменная типа STRING, содержащая символьное представ ление цифрового значения. Функция приводит переменную типа STRING, содержащую символь ное представление цифрового значения, в цифровую переменную, содержащую соответствующее цифровое значение. Пример. Следующая строка кода приводит строку «2» к цифро вой переменной со значением 2: nNuffl = Val ( - 2 " )
Хотелось бы также отметить наличие следующих функций, которые не полностью подпадают под определение «функции приведения ти пов», но при этом имеют довольно большое значение для работы. Функция
Описание
Asc (strjng$)
Возвращает ASCII-код символа s t r i n g $
Chr$ (charcode%)
Возвращает символ со значением ASCII-кода, равным charcode^
функции работы с массивами
Фрикции Ссиг (expression)
Описание Трансформирует выражение expression в значение типа Currency
СОЫ (expression)
Трансформирует выражение expression в значение типа Double Трансформирует выражение expression в значение типа
Cint (expression)
59
Integer CLng (expression)
Трансформирует выражение expression в значение типа Long
CSng (expression)
Трансформирует выражение expression в значение типа Single
CStr (expression)
Трансформирует выражение expression в значение типа String Трансформирует выражение expression в значение типа Variant Date
CVDate (expression)
Функции работы с массивами Функции работы с массивами являются встроенными функциями языка и позволяют работать с массивами (получать длину массива, менять его параметры, добавлять новые значения и т. д.). Их набор напрямую зависит от выбранного языка.
TSL (WinRunner) TSL предоставляет пользователю всего одну функцию для работы с массивами: delete array [ subscript ]
Функция удаляет указанный элемент массива. Пример. Следующая строка удаляет второй элемент массива filenames: delete filenames[l];
4TEST (SilkTest) 4test предоставляет пользователю следующие функции для работы с массивами. ArrayFind (aArray, aElem [. iMaxIndex])
где aArray — имя массива; aElem — искомый элемент; iMaxIndex — максимальное количество элементов, включенных в поиск.
60
Глава 3. Язык скриптов
Функция возвращает индекс элемента aElem в массиве аАггау (О, если элемент не найден). Пример. Следующий блок кода возвращает 3: aiTempPerDay = {...} {10. 12. 8. 17} {-1. 0. 17. -9} {U. 1. 1. 0} {75. 32. 18. 103} {9. -7. -2. 3} ArrayFind (aiTempPerDay[l]. 8) ArrayResize (аАггау, iNewSize [, iDim])
Здесь аАггау- имя массива; iNewSize — новое количество элементов; iDim — измерение массива. Функция изменяет заданные размеры массива. Пример. Следующий блок кода создает массив 5 х 4 и перезадает его как массив 5 x 8 : INTEGER aiTempPerDay[5][4] ArrayResize (aiTempPerDay. 8. 2) ArraySize (аАггау [, iDim])
Здесь аАггау — имя массива; iDim — измерение массива. Функция возвращает количество элементов массива. Пример. Следующий блок кода возвращает 4: INTEGER aiTempPerDay[5][4] ArraySize (aiTempPerDay, 2) ArraySort (аАггау [, iMaxIndex])
Здесь аАггау — имя массива; iMaxIndex — максимальное количество элементов, включенных в сортировку. Функция сортирует массив. Пример. Следующая строка кода сортирует первые три элемента массива: ArraySort (aiTempPerDay[5]. 3)
Для работы со списками 4test использует следующие функции: ListAppend (IList. aElem)
где IList ~ имя списка; aElem — искомый элемент. Функция добавляет значение aElem в список IList.
функции работы с массивами
61
Пример. Следующая строка кода добавляет значение apples в спи сок IsFruit: ListAppend (IsFruit. "apples") ListCount (IList)
Функция возвращает количество элементов в списке. Пример. Следующий блок кода возвращает 3: LIST OF INTEGER liNumber = { . . . }
-1 О IListCount (liNumber) ListDelete (IList, ilndex)
Здесь IList — имя списка; ilndex — искомый элемент. Функция удаляет указанный элемент списка. Пример. Следующая строка кода удаляет третий элемент списка: ListDelete (liNum. 3) Listlnsert (IList. ilndex, altem)
Здесь IList — имя списка; ilndex — позиция изменения элемента; aElem — вставляемый элемент. Функция вставляет значение aElem в позицию ilndex списка IList. Пример. Следующий блок кода вставляет значение m во второй элемент списка 1 s: LIST Is = { . . . } "g" "s"ListInsert ( I s , 2. "m")Print (Is) / / список: {g. m. s} ListMerge (lOrig. 1Merge [. iMergePos])
Здесь lOrig — имя первого списка; 1 Merge — имя второго списка; iMergePos -- номер элемента первого списка, в который вставляется второй список. Функция объединяет списки lOrig и 1 Merge. Пример. Следующий блок кода объединяет два списка: LIST X = { . . . }
1 2ListMerge (х, {5. 6}) / / список: { 1 , 2. 5. 6}
62
Глава 3. Язык скриптов
ListFind (IList. altem)
Здесь IList ~ имя списка; altem — искомый элемент. Функция возвращает индекс элемента altem в списке IList (О, если элемент не найден). Пример. Следующий блок кода возвращает 2: LIST IsFruit«{...} "apples" "oranges" "bananas"Print (ListFind (IsFruit, "oranges") ListRead (IsList. sFileName)
Здесь IList — имя списка; sFileName — имя файла. Функция считывает значения из файла sFileName в список IList. Пример. Следующая строка кода считывает значения из файла fruit.txt и записывает их в список IsFruit: ListRead (IsFruit, "fruit.txt" ) ListSort (IList)
Функция сортирует список IList. Пример. Следующий блок кода сортирует список: LISTliNum«{...}1010-lListSort (liNum) //список: {-1, О, 1, 10} ListPrint (IList)
Функция распечатывает список IList в файл результатов. Пример. Следующий блок кода распечатывает список: LIST I F r u i t - { . . . } "apples" "oranges" "bananas" ListPrint (IFruit) // Prints:// apples// oranges// bananas
SQABasic (Robot) SQABasic предоставляет пользователю следующие функции для ра боты с массивами. Erase Array [. Array ]
Функция удаляет все элементы массива (реинициализирует их). Пример. Следующая строка удаляет элемент массива filenames: Erase filenamesО
функции работы с массивами
63
ReDim [ Preserve ] variableName ( subscriptRange . ... ) [As [ New ] type] , ...
Здесь variableName — имя изменяемого массива; subscriptRange — но вые границы массива; type — тип данных массива. Функция изменяет заданные границы массива. Если опция Preserve указана, то значения массива сохраняются. В противном случае пе ределанный массив реинйциализируется. Пример. Следующий блок кода создает динамический массив и перезадает его как массив из 11 элементов: Dim varrayO as Double ReDim varray(ll) Option Base lowerBound^
Функция устанавливает нижнюю границу массива по умолчанию (О или 1). Пример. Следующая строка устанавливает нижнюю границу мас сива как 1: Option Base 1 LBound( arrayname [, dimension ] )
Здесь arrayname — имя массива; dimension — измерение массива. Функция возвращает нижнюю границу массива. Пример. Следующий блок кода создает динамический массив и возвращает 1 как нижнюю границу массива: Option Base 1 Dim varrayO as Double LBound(varray) UBound( arrayname [. dimension ] )
Здесь arrayname — имя массива; dimension — измерение массива. Функция возвращает верхнюю границу массива. Пример. Следующий блок кода создает динамический массив и возвращает 11 как верхнюю границу массива: Dim varrayO as Double ReDim varray(ll) UBound(varray)
64
Глава 3. Язык скриптов
Функции работы со строками Функции работы со строками являются встроенными функциями язы ка и позволяют работать со строками (искать значения в строке, по лучать длину строки, сравнивать строки и т. д). Их набор напрямую зависит от выбранного языка.
TSL (WinRunner) TSL доставляет пользователю следующие функции работы со стро ками. ascii(string)
Функция возвращает код символа. Пример. Следующая строка кода возвращает 77: asciiC'M"); compare_text ( s t r l , str2 [. charsi, chars2 ] )
Здесь strl и str2 — сравниваемые строки; charsi — значение в strl, которое следует принимать как идентичное значению chars2 в str2; chars2 — значение в str2, которое следует принимать как идентичное значению charsi в strl. Функция сравнивает две строки. Пример. Следующая строка кода сравнивает две строки, игнори руя разницу между «I» и «1»: compare_text ("File". "File", "I". "1"); index ( stringl. string2 )
Здесь stringl — строка, в которой производится поиск; string2 — стро ка, которую ищут. Функция возвращает положение string2 в stringl (О, если строка не найдена). Пример. Следующая строка кода возвращает 4: index("a1ibaba","ba"); length ( string )
Функция возвращает длину строки. Пример. Следующая строка кода возвращает 8: length ("universe"):
функции работы со строками
65
index ( string, regularexpression )
Здесь string — строка, в которой производится поиск; regular^ expression — «маска» поиска. Функция возвращает положение регулярного выражения («маски» поиска) в строке string (О, если строка не найдена). Пример. Следующая строка кода возвращает 13: match ("the name is Bond", "[A-Z][a-2]*"); s p l i t ( s t r i n g , array [ , fie1d_separators ] )
Здесь string — разбиваемая строка; array — массив, куда будет про изведено разбиение; fie1d_separators — флаг разбивки. Функция разбивает строку на массив строк по флагу разбивки. Пример. Следующая строка кода разбивает строку на массив, со стоящий из элементов ["С:", "Temp", "WinRunner"]: s p l i t ("CrWTempWWinRunner", path_array, " W " ) : s p r i n t f ( format, expl, exp2
expn )
Здесь format — строка и спецификатор формата; ехр — выражение, которое будет отформатировано. Функция возвращает отформатированную версию данной строки. Пример. Следующий блок кода возвращает «The abbreviation for January is: Jan»: month = "January"; x = s p r i n t f ("The abbreviation for January i s : ^.3s", month): substr ( s t r i n g , position [, length ] )
Здесь string — данная строка; position — позиция в данной строке; length — длина отрезаемой части. Функция возвращает часть данной строки длиной length, считая от position. Пример. Следующая строка кода возвращает строку «Ночной»: substr ("Ночной Дозор". 1, 6): tolower ( s t r i n g )
Функция возвращает данную строку в нижнем регистре. Пример. Следующая строка кода возвращает строку «ночной до зор»: tolower ("НОЧНОЙ ДОЗОР"):
66
Глава 3. Язык скриптов
toupper ( string )
Функция возвращает данную строку в верхнем регистре. Пример. Следующая строка кода возвращает строку «НОЧНОЙ ДОЗОР»: toupper ("ночной дозор");
4TEST (Silkiest) 4test предосташшет пользователю саедующие функции работы со стро ками. IsAlpha (sString)
Функция проверяет, является ли первый символ в строке буквен ным значением. Пример. Следующая строка кода возвращает TRUE: IsAlpha ("hello") IsDigit (sString)
Функция проверяет, является ли первый символ в строке буквенным значением. Пример. Следующая строка кода возвращает TRUE: IsDigit ("123heno") IsSpace (sString)
Функция проверяет, является ли первый символ в строке буквенным значением. Пример. Следующая строка кода возвращает TRUE: IsSpace (" hello") GetField (sString, sDelim. iField)
Здесь sString — искомая строка; sDelim — флаг разбиения (символ, на основе которого будет произведена разбивка); iField ~ номер воз вращаемого сегмента. Функция возвращает сегмент строки по заданным параметрам. Пример. Следующая строка кода возвращает «паше»: GetField ("name|rank|seriair. '\\
I)
Left (sString. iNumChars)
Здесь sString — искомая строка; iNumChars — количество возвращае мых символов.
функции работы со строками
67
Функция возвращает заданное количество символов, начиная от са мого левого символьного значения. Пример. Следующая строка кода возвращает «Segue»: Left ("Segue Software". 5) Right (sString. iNumChars)
Здесь sString — искомая строка; iNumChars — количество возвращае мых символов. Функция возвращает заданное количество символов, начиная от са мого правого символьного значения. Пример. Следующая строка кода возвращает «World»: Right ("Hello World". 5) Ltrim (sToStrip)
Функция возвращает строку с удаленными начальными пробелами. Пример. Следующая строка кода возвращает «Has whitespace »: Ltrim (" Has whitespace ") Rtrim (sToStrip)
Функция возвращает строку с удаленными конечными пробелами. Пример. Следующая строка кода возвращает « Has whitespace»: Rtrim (" Has whitespace ") Trim (sToStrip)
Функция возвращает строку с удаленными пробелами. Пример. Следующая строка кода возвращает «Has whitespace»: Trim (" Has whitespace ") Space (iCount)
Функция возвращает строку с заданным количеством пробелов. Пример. Следующая строка кода выводит «12345 67890»: Print ("12345" + Space (10) + "67890") Tabs(iAmount) Функция возвращает строку с заданным количеством табуляций. Пример. Следующая строка кода выводит «string with leading tabs»: Print C{Tabs(2)}stringwith leading tabs")
68
Глава 3. Язык скриптов
Replicate (sOrig, iCopies)
Функция возвращает значение строки (sOrig) заданное количество (iCopies) раз.
Пример. Следующая строка кода возвращает «АААА»: Replicate ("А", 4) Lower ( string )
Функция возвращает данную строку в нижнем регистре. Пример. Следующая строка кода возвращает строку «ночной до зор». Lower ("НОЧНОЙ ДОЗОР")
Upper (sToConvert)
Функция возвращает данную строку в верхнем регистре. Пример. Следующая строка кода возвращает строку «НОЧНОЙ ДОЗОР». Upper ("ночной дозор") MatchStr (sPattern. sString)
Здесь sPattern — «маска» поиска; sString — искомая строка. Функция проверяет строку на присутствие «маски» поиска. Пример. Следующая строка кода возвращает TRUE: MatchStr ("*HELLO*". "hi hello there") SubStr (sString, iPos [, iLen])
Здесь sString — данная строка; iPos — позиция в данной строке; iLen — длина вырезаемой части. Функция возвращает часть данной строки длиной iLen, считая от position. Пример. Следующая строка кода возвращает строку «Ночной»: SubStr ("Ночной Дозор", 1. 6) StrPos (sSubstr, sTarget [, bBackward]))
Здесь sSubstr — строка, в которой производится поиск; sTarget — строка, которую ищут; bBackward — флаг начала поиска (TRUE, еслр! поиск производится с конца, не указывается, если с начала). Функция возвращает положение sTarget в sSubstr (О, если строка не найдена).
функции работы со строками
69
Пример. Следующая строка кода возвращает 4: StrPos("ba","a11baba") StrTran (sOrig, sSearch, sReplace)
Здесь sOrig — данная строка; sSearch — Р1скомая строка; sReplace — строка-замена. Функция заменяет sSearch на sReplace в sOrig. Пример. Следующая строка кода возвращает «one & two & three»: StrTran ("one and two and three", "and". "&") Stuff (sOrig, iPos, ILen, sReplace)
Здесь sOrig ~ данная строка; iPos — начальная позиция изменения; ILen — количество удаляемых символов; sReplace — вставляемые значения. Функция вставляет sReplace в sOrig, начиная с IPos, удалив при этом ILen символов, начиная с iPos. Пример. Следующая строка кода возвращает «hello OUT there»: Stuff ("hello there",7.0."OUT")
Пример. Следующая строка кода возвращает «hello WORLD»: Stuff ("hello there", 7,5. "WORLD)
Пример. Следующая строка кода возвращает «hello»: Stuff ("hello there". 6.6."") Len (sString)
Функция возвращает длину строки. Пример. Следующая строка кода возвращает 5: Len ("Segue")
SQABasic (Robot) SQABasic предоставляет пользователю следующие функции работы со строками. GetField$( string! . field_number^ , separator_chars$ ) где strings — искомая строка; field_number^ — номер возвращаемого сегмента; separator_chars$ — флаг разбиения (символ, на основе ко торого будет произведена разбивка). Функция возвращает сегмент строки по заданным параметрам.
70
Глава 3. Язык скриптов
Пример. Следующая строка кода возвращает «name»: GetField$ C'namelranklseriair. '\\ I) Len( strings )
Функция возвращает длину строки. Пример. Следующая строка кода возвращает 5: Len ("Segue") Lefts( strings, length* )
Здесь strings — искомая строка; length* — количество возвращае мых символов. Функция возвращает заданное количество символов, начиная от са мого левого символьного значения. Пример. Следующая строка кода возвращает «Segue»: Lefts ("Segue Software", 5) RightS( strings, length* )
Здесь strings — искомая строка; length* — количество возвращаемых символов. Функция возвращает заданное количество символов, начиная от са мого правого символьного значения. Пример. Следующая строка кода возвращает «World»: Rights ("Hello World", 5) LTrimS( expression )
Функция возвращает строку с удаленными начальными пробелами. Пример. Следующая строка кода возвращает «Has whitespace »: LTrimS ("Haswhitespace ") RTrimS( expression )
Функция возвращает строку с удаленными конечными пробелами. Пример. Следующая строка кода возвращает « Has whitespace»: RTrimS (" Has whitespace ") TrimS( expression)
Функция возвращает строку с удаленными пробелами. Пример. Следующая строка кода возвращает «Has whitespace»: Trim (" Has whitespace ")
функции работы со строками
71
LCase$( strings )
Функция возвращает данную строку в нижнем регистре. Пример. Следующая строка кода возвращает строку «ночной до зор»: LCase$ ("НОЧНОЙ ДОЗОР")
UCase$( string* )
Функция возвращает данную строку в верхнем регистре. Пример. Следующая строка кода возвраи^ает строку «НОЧНОЙ ДОЗОР»: UCase& ("ночной дозор") Space$( number )
Функция возвращает строку с заданным количеством пробелов. Пример. Следующая строка кода печатает «12345 67890»: SQALogMessage sqaNone, "12345" & Spaced (10) & "67890","" Strings ( number , strings )
Функция возвращает значение строки (strings) заданное количест во (number) раз. Пример. Следующая строка кода возвращает «АААА»: Strings (4, "А") InStr( [starts.] stringlS. string2S )
Здесь stringlS — строка, в которой производится поиск; string2S — строка, которую ищут; starts — индекс начала поиска; 1 — начало строки. Функция возвращает положение string2S в stringlS (О, если строка не найдена). Пример. Следующая строка кода возвращает 4: InStr("alibaba","ba") StrComp( StringlS . string2S [ . compare* ] )
Здесь StringlS и string2S — сравниваемые строки; compare* — флаг учета регистра (О — с учетом регистра, 1 — без учета регистра ). Функция сравнивает две строки. Пример. Следующая строка кода сравнивает две строки, игнори руя регистр: StrComp ("file". "File". "1")
72
Глава 3. Язык скриптов
SetField$( string$, field_number^, fie1d$, separator_chars$ ) Здесь strings — данная строка; field_number^ — начальная позиция изменения; fieldS — новое значение символа; separator_chars$ — сим вол-разделитель. Функция заменяет символы от field_number^ до следующего separator_chars$ на fields в strings. Пример. Следующая строка кода возвращает « Винниченко». SetFie^d("Илbя Винниченко'М," "," ")
strings LIKE patterns
Здесь strings — искомая строка; patterns — «маска» поиска. Оператор проверяет строку на присутствие «маски» поиска. Пример. Следующая строка кода возвращает TRUE: "henо" LIKE " [ a * z ] " HexS( number )
Функция конвертирует десятичное число в шестнадцатеричное и воз вращает его строковое значение. Пример. Следующая строка кода возвращает 7В: HexS ("123") OctS( number )
Функция конвертирует десятичное число в восьмеричное и возврапщет его строковое значение. Пример. Следующая строка кода возвращает 173: OctS ("123") MidS( s t r i n g s , startJ^ [,
lengthJT] )
Здесь strings — данная строка; starts — позиция в данной строке; length^ — длина вырезаемой части. Функция возвращает часть данной строки длиной length^, счргтая от starts. Пример. Следующая строка кода возвращает строку «Ночной». MidS ("Ночной Дозор". 1 , 6)
Глава 4 Элементы интерфейса и их функции
Эта глава, по сути, — самая важная в книге: в ней описываются ос новные элементы упгтерфейса пользователя и функтп! работы с IHIMH. Для начала, как и ранее, сформулируем наши запросы как ниженеров-автоматизаторов к набору функций для каждого конкретного элемента, а потом на примере самых распростране1П1ых программных продуктов для автоматизации процессов тестирования рассмотрим, как это сделано в «реальном мире». Перечислим эти самые «основные элементы интерфейса пользова теля»: • • • • • • • • • • • •
Window (Окно); Menu (меню); ListBox/ComboBox (Раскрывающийся список/Поле со списком); Button (Кнопка); CheckBox/RadioButton (Флажок/Переключатель); EditBox (Поле ввода); Table (Таблица); Scroll (Ползунок); Tab (Вкладка); Label (Метка); Image Button (Вставка изображения) — применяется только в Веб; Link (Ссылка ) — применяется только в Веб.
74
Глава 4. Элементы интерфейса и их функции
Window Элемент Window (Окно) является основой, своеобразным плацдармом для остальных элементов интерфейса пользователя, без него невоз можно представить ни одну пользовательскую программу, использую щую графический интерфейс пользователя (естественно, что это утверждение истинно только для операционных систем семейства Microsoft Windows, о которых идет речь в данной книге). Какие же функции этого элемента необходимы во время работы с ним? • Активирование окна. • Сворачивание окна. • Разворачивание окна. • Восстановление первоначального вида окна. Теперь на примере широко распространенных программных продук тов для автоматизации процессов тестирования посмотрим, как эти функции реализованы.
Активирование окна Когда одновременно работают два и более приложений, бывает не обходимо активировать окно тестируемого приложения, то есть рас положить его поверх остальных окон. WinRunner set^window (windowname. timeout)
где windowname — логическое имя или физическое описание окна; timeout — время ожидания появления окна в миллисекундах. Пример. Активирование окна PizzaOrder: set_window ("PizzaOrder", 50):
при этом, если окно в данный момент отсутствует на экране, скрипт ожидает его появления в течение 50 мс. SilkTest Wi ndowname.SetActi ve()
где windowname ^ логическое имя окна. Пример. Следующая строка кода активирует окно PizzaOrder: Pi zzaOrder.SetActi ve()
Window
75
Rational Robot Window SetContext, recMethod$
где recMethod$ — способ идентификации окна. Пример. Активирование окна PizzaOrder. Window SetContext, -Caption-PizzaOrder"
Сворачивание окна Когда одновременно открыто несколько окон тестируемого прило жения, бывает необходимо свернуть одно окно и активировать дру гое (см. предыдущую функцию). WinRunner win^min (windowname)
где windowname — логическое имя или физическое описание окна. Пример. Следующая строка кода сворачивает окно PizzaOrder: win__min ("PizzaOrder");
SilkTest Windowname.MinimizeO
где windowname — логическое имя окна. Пример. Сворачивание окна PizzaOrder: PizzaOrder.Minimi zeO
Rational Robot Window WMinimize. recMethod$
где recMethod$ — способ идентификации окна. Пример. Код для сворачивания окна PizzaOrder: Window WMinimize. "Caption-PizzaOrder"
Разворачивание окна Иногда бывает необходимо развернуть ранее свернутое окно. WinRunner win__max (windowname)
где windowname — логическое имя или физическое описание окна. Пример. Следующая строка кода разворачивает окно PizzaOrder: win max ("PizzaOrder");
76
Глава 4. Элементы интерфейса и их функции
SilkTest Windowname.MaximizeO
где windowname — логическое имя окна. Пример. Разворачивание окна PizzaOrder: Р1zzaOrder.Maxi mi ze() Rational Robot Window WMaximize. recMethod$
где recMethod$ — способ идентификации окна. Пример. Код для разворачивания окна PizzaOrder: Window WMaximize. "Caption=PizzaOrder"
Восстановление первоначального вида окна Иногда бывает необходимо развернуть ранее свернутое окно или же вернуть развернутому окну его первоначальное состояние. Функция может применяться лишь после использования функций сворачива ния или разворачивания. WinRunner w i n r e s t o r e (windowname)
где windowname — логическое имя или физическое описание окна. Пример. Следующая строка кода возвращает окну PizzaOrder пер воначальную форму/положение: winrestore ("PizzaOrder"); SilkTest
Wi ndowname.Restore()
где windowname — логическое имя окна. Пример. Восстановление первоначальной формы/положения окна PizzaOrder: Pi zzaOrder.Restore() Rational Robot
Window RestorePos, recMethod$
где recMethod$ — способ идентификации окна. Пример. Следующая строка кода возвращает окну PizzaOrder пер воначальную форму/положение: Window RestorePos, "Caption=PizzaOrder"
Menu
77
Menu Элемент Menu (Меню) представляет собой рас крывающийся список параметров, позволяющих . „ выполнить то или иное деистврхе. Этот элемент \^^^^^!^!А может иметь несколько субуровней, в свою оче редь являющихся элементами класса Menu. Этот элемент можно встре тить практически в любом приложении, написанном для использо вания в операционной системе Windows. Необходихмые функции этого элемента: • выбор любого элемента из списка; • выбор элемента из списка в субуровне другого элемента. Рассмотрим, как реализованы эти функции, на примере наиболее широко распространенных программных продуктов для автоматиза ции процессов тестирования.
Выбор элемента из списка Назначение данной функции, как следует из названия, ~ выбор нужного варианта из списка. WinRunner menu_se1ect_item (menu;item)
где menu — логическое имя меню, ; — разделитель между уровнями меню, item — логическое имя параметра или его порядковый номер с символом #. Пример. Следующая строка кода выбирает Optionl: menu_se1ect_item ("Menul.-Optionl") ; Пример. Другой вариант выбора Optionl: menu_select_item ("Menul;#l"); SilkTest Menu.MenuItem.PickO
где Menu — логическое имя меню; Menultem — логическое имя пара метра. Пример. Следующая строка кода выбирает Optionl: Menul.Optionl.PickO
78
Глава 4. Элементы интерфейса и их функции
Rational Robot MenuSelect menuPath$
где menuPath$$ — способ идентификации пути к выбираемому пара метру: • MenuName->OptionName — для полных имен; • Menu=MenuName->pos(#) — для использования порядкового номера параметра. Пример. Строка кода выбирает Optionl: MenuSelect "Menul->Optionl" Пример. Другой вариант выбора Optionl: MenuSel ect "Menu-Menul • >pos(1)"
Выбор элемента из списка в субуровне другого элемента По сути эта функция ничем не отличается от предыдущей. Причи на, по которой она описывается отдельно, — показать, как различная архитектура программных продуктов автоматизации тестирования влияет на синтаксис исполняемых функций. WinRunner menu_select_item (menu;item)
где menu — логическое имя меню; ; — разделитель между уровнями меню; item -- логическое имя параметра или его порядковый номер с символом #. Пример. Следующая строка кода выбирает SubMenul: menu^selectjtem ("Menul:0ption2;SubMenul"): SilkTest Menu.MenuItem.PickO
где Menu •- логическое имя меню; Menultem — логическое имя пара метра. Пример. Следующая строка кода выбирает SubMenul: Menul.0ption2.SubMenul. PickO Rational Robot MenuSelect menuPath$
где menuPath$$ — способ идентификации пути к выбираемому пара метру:
ListBox/ComboBox
79
• MenuName->OptionName — для полных имен параметров; • Menu=MenuName->pos(#) — для использования порядкового номера параметра. Пример. Выбор параметра SubMenul: MenuSel ect "Menul - >Opti оп2 - >SubMenul"
ListBox/ComboBox Элемент ListBox (Раскрывающийся список), как и его производная ComboBox (Поле со списком), представляет собой список какихлибо элементов, как просто несущих смыс ловую нагрузку (простой набор данных), так и управляющих выбо ром последующего действия. Из представленного элементом ListBox списка пользователь может выбрать один пункт или, нажав и удер живая клавишу Ctrl, — несколько пунктов. Важным аспектом функщ10нальности ComboBox является возможность набрать название нужно го элемента с клавиатуры, что может быть полезным, если вы знаете, что именно хотите выбрать. В процессе работы с элементом ListBox/ComboBox полезными будут такие его возможности: • • • • • •
выбор элемента списка по его значению; выбор элемента списка по его порядковому номеру; выбор нескольких элементов списка по их значениям; выбор нескольких элементов списка по их порядковым номерам; определение порядкового номера элемента списка по его значению; определение значения элемента списка по его порядковому но меру; • определение количества элементов в списке; • определение значений всех элементов в списке; • определение значения выбранного элемента списка. Теперь на примере наиболее распространенных программных продук тов для автоматизации процессов тестирования рассмотрим, как реа лизованы эти функции.
90
Глава 4. Элементы интерфейса и их функции
Выбор элемента списка по его значению WinRunner l i s t selectjtem ( l i s t , item)
где list — логическое имя или фр13ическое описание списка; item — выбираемый элемент. Пример. Следующая строка кода выбирает элемент Visa из спис ка Credit Card: l i s t s e l e c t i t e m ("CreditCard". "Visa"); SilkTest ComboBox/Li stBox.Select(sItern)
где ComboBox/ListBox — логическое имя списка; si tern — выбираемый элемент. Пример. Выбор элемента Visa из списка Credit Card: CreditCard.Select("Visa") Rational Robot ComboBox/ListBox Click. recMethod$. Coords$
где recMethod$ — способ идентификащп! списка; Coords — х- и у-координаты закладки. Пример. Строка кода для выбора элемента Visa из списка Credit Card: ComoBox Click. "ObjectIndex=l:\;ItemText'=Visa". "Coords=50,25"
Выбор элемента из списка по его порядковому номеру WinRunner list_select_item ( l i s t , item)
где list — логическое имя или физическое описание списка; item — выбираемый элемент. Пример. Следующая строка кода выбирает элемент Visa из спи ска Credit Card. list^selectjtem ("CreditCard". "#1"): SilkTest Co«boBox/Li StBox.Select(sitem)
где ComboBox/ListBox — логическое имя списка; si tem — выбираемый элемент.
ListBox/ComboBox
81
Пример. Строка кода для выбора элемента Visa из списку Credit Card: CfednCard. Se1 ect ("#е;') Rational Robot ComboBox/LlstBcK Click. recMethod$. Ca?rds$
где recMethod$ — способ идентификации списка; Coords — z- и у-координаты закладки. Пример. Следующая стрскё! кода выбирает элемент Visa из списка Credit Card: ComoBox Click, "ObjectIndex==i;\;IteraIndex=^l", "Coords=50.25"
Выбор нескольких элементов из списка по их значениям WinRunner list_select_multi_iterns ( l i s t , items)
где list — логическое имя или физическое описание спигка; itents — СЛИСОК выбираемых элементов. Пример. Следующая строка кода выбирает элементы January и Feb ruary из списка Month: l i s t s e l e c t j n u l t i i terns ("Month", "January, February"); SilkTest CornboBox/ListBox.MultiSelect(sItem)
где ComboBox/ListBox — логическое имя списка; sItem — выбираемый элемент. ПРИМЕЧАНИЕ
Чтобы обеспечить возможность множественного выбора, необ ходимо использовать функцию несколько раз. Пример. Следующий блок кода выбирает элементы January и Feb ruary из списка Month: Month.MultiSelect("January") Month.MultiSelect("February") Rational Robot
Из-за особенностей своей архитектзфы Rational Robot не имеет воз можности выполнить данную операцию в одной фзгнкции. Необхо димо написать функцию пользователя.
82
Глава 4. Элементы интерфейса и их функции
Выбор нескольких элементов из списка по их порядковым номерам WinRunner list_select_multijtems ( l i s t , items)
где list — логическое имя или физическое описание списка; items — список выбираемых элементов. Пример. Следующая строка кода выбирает элементы January и Feb ruary из списка Month: list^^select^multijtems ("Month", "#1.7*2"); SilkTest ComboBox/ListBox.MultiSelect(sItem)
где ComboBox/ListBox — логическое имя списка; sltem — выбираемый элемент. ПРИМЕЧАНИЕ Чтобы обеспечить возможность множественного выбора, необ ходимо использовать функцию несколько раз.
Пример. Следующий блок кода выбирает элементы January и Feb ruary из списка Month: Month.MultiSelect("#0") Month.MultiSelect("#l") Rational Robot
Опять понадобится написать функцию пользователя.
Определение порядкового номера элемента списка по его значению WinRunner 1 i st_get_item^num (1 i st, item, out__val ue)
где list — логическое имя или физическое описание списка; item — значение элемента; out^value — переменная, возвращающая порядко вый номер элемента. Пример. Следующая строка кода возвращает порядковый номер элемента Visa: list__getjtem_num ("CreditCard", ••Visa",out_value):
ListBox/ComboBox
83
SilkTest ComboBox/ListBox.FindltemCsItem)
где ComboBox/ListBox — логическое имя списка; sItem — значение эле мента. Пример. Строка кода, возвращающая порядковый номер элемен та Visa: out_value « CreditCard.FindltemC'Visa") Rational Robot
Для выполнения описанного действия необходимо написать функ цию пользователя.
Определение значения элемента списка по его порядковому номеру WinRunner 1 ist__get_item (1 i s t , item^num, out__val ue)
где list — логическое имя или физическое описание списка; item_ num — порядковый номер элемента; out__value — переменная, содер жащая возвращаемое значение элемента. Пример. Следующая строка кода возвращает значение элемента с порядковым номером 1: list_getjtem ("CreditCard", "#l".out_value); SilkTest ComboBox/Li stBox.GetItemText(sitem)
где ComboBox/ListBox — логическое имя списка; sItem -- порядковый номер элемента. Пример. Строка кода, возвращающая значение элемента с поряд ковым номером 1: out^value » CreditCard.GetItemText("#0") Rational Robot
Для выполнения этого действия необходимо написать функцию поль зователя.
Определение количества элементов в списке WinRunner 1 ist_get_info (1 i s t . "count\out^^value)
где list — логическое имя или физическое описание списка; out_value — переменная, содержащая возвращаемое значение.
84
Глава 4. Элементы интерфейса и их функции
Пример. Следующая строка кода возвращает количество элемен тов в списке Credit Card: list_get_info ("CredltCard", "count\out_val'je): SilkTest
ComboBox/L1stBox.Get!temCount() где CofflboBox/LlstBcx — логическое кмя списка. Пример. Подсчет количества элементов в стеске Credit Card: out^yalue = CreditCard.GetltemCountO Ratlonaf Robot SQAGetPropertyf recMethod$.property.out value)
где recM€thod$ — способ идеитификадии строки ввода; property — на звание запрашиваемого свойства; out^val ue — переменная, храня2дая значение запрашиваемого свойства. Пример. Строка кода, возвраидающая количество элементов в спи ске Credit Card: SQAGetPropertyC"Туре« СопиюВох: Naine=CreditC6rd"."ItenCaint",out_yalue)
Определение значения всех элементов в списке WinRunner
Из-за особенностей своей архитектуры WiaRunner не имеет воз можности выполнить данную операцию в одной функции. Для вы полнения этого действия необходимо написать функцию пользова теля. SilkTest ComboBox/Li stBox.GetContents()
где ComboBox/Li stBox — логическое имя списка. Пример. Следующая строка кода возвращает значения всех эле ментов в списке Credit Card: out^value = CreditCard.GetContentsO Rational Robot
Из-за особенностей своей архитектуры Rational Robot не имеет воз можности выполнить данную операцию в одной функции, придется написать функцию пользователя.
Button
85
Определение значения выбранного эпемента списка WinRunner 11 st_get_5el ected (1 i st, out_\ral ue, out^nura)
где list — логическое имя или физическое описание списка; out_ value — переменная, содержащая возвращаемое значение элемента; outnum — перСхменная, содержащая возвращаемый порядковый но мер элемента. Пример. Следующая строка кода возвращает значение и поряд ковый номер выбранного элемента: I1st_get_selected ("CreditCard", out__valii€, out^nuw); SflkTest Combc^x/Li stBox. ReturnTypeC)
где ComboBox/ListBox — логическое имя списка; ReturnType — функция возврата данных; GetSel Index — значение выбранного элемента; GetSelText — порядковый номер выбранного элемента. Пример. Строка кода, возвращающая порядковый номер выбран ного элемента: out^num * CreditCard.GetSel IndexC)
Пример. Строка кода, возвращающая значение выбранного эле мента: out__value =» CreditCard, GetSelText О Rational Robot
Для выполнения этого действия необходимо написать функцию пользователя.
Button Элемент Button (Кнопка) является одним из наиболее распространенных и важных элементов графического ин терфейса пользователя. Трудно себе представить Windows-профамму без кн(шок ОК или Cancel. Фактически, в большинстве случаев элемент Button — это то, с чего начинается действие. Можно сказать, что это один из основных тружеников Windows. Вы никогда не за думывались над тем, сколько компьютерного времени мы проводим (нет, не перезагружаясь), щелкая клавишами мыши и нажимая все возможные кнопки?
86
Глава 4. Элементы интерфейса и их функции
Какие же функции этого элемента будут необходимы во время рабо ты с ним? • Возможность нажать кнопку (куда ж без этого). • Возможность получить сведения о состоянии элемента. Рассмотрим, как реализованы эти функции.
Нажатие кнопки WinRunner button^press (button)
где button — логическое имя или физическое описание кнопки. Пример. Следующая строка кода задает нажатие кнопки Submi't: button press ("Submit"): SilkTest PushButton.Click ()
где PushButton — логическое имя кнопки. Пример. Нажатие кнопки Submit: Submit.ClickO Rational Robot PushButton Click. recMethocl$
где recMethod$ — способ идентификации кнопки. Пример. Строка кода, задающая нажатие кнопки Submit: PushButton Click. "Type«PushButton;Name-Submit"
Получение сведений о состоянии элемента WinRunner button_get_infо (button.property.out^value)
где button — логическое имя или физическое описание кнопки; pro perty — название запрашизаемого свойства; out^value — переменная, хранящая значение запрашиваемого свойства. Пример. Следующая строка кода возвращает состояние кнопки Submit на данный момент: button__getJnfo ("Submit", "enabled", out^value); SilkTest PushButton.6etProperty(property)
где PushButton — логическое имя кнопки; property — название запра шиваемого свойства.
CheckBox/RadioButton
87
Пример. Строка кода, возвращающая состояние кнопки Submit на данный момент: out^value » Submit.GetPropertyC'bEnabled") Rational Robot SQAGetProperty( recMethod$. property, out__val ue)
где recMethocl$ — способ идентификации кнопки; property ~ название запрашиваемого свойства; out^value — переменная, хранящая значе ние запрашиваемого свойства. Пример. Следующая строка кода возвращает состояние кнопки Submit на данный момент: SQAGetProperty("Type=PushButton;Name»Submit"."Enabled",out^value)
CheckBox/RadioButton Вообще-то, CheckBox (Флажок) и RadioButton (Переклю чатель) -- это различные элементы. Причина, по которой между ними поставлен знак равенства, проста. Кроме внеш него вида они отличаются только тем, что позволяют выбрать раз ное количество вариантов из нескольких элементов класса. Можно выбрать несколько (даже все сразу) элементы CheckBox и только один из элементов RadioButton. Набор функций у этих элементов, соответ ственно, одинаков. Какие функции этих элементов необходимы? • Выбор любого параметра. • Отмена выбранного параметра. • Получение информации о состоянии элемента. Теперь на примере программных продуктов для автоматизации про цессов тестирования рассмотрим, как реализованы эти функции.
Выбор параметра WinRunner button^set (button. ON)
где button — логическое имя или физическое описание кнопки. Пример. Следующая строка кода выбирает вариант Large из спи ска параметров Pizza Туре: button^set ("Large". ON);
88
Глава 4. Элементы интерфейса и их функции
SilkTest
Частным случаем реализации данной функции является то, что SilkTest из-за особенностей своей объектно-ориентированной архитек туры рассматривает CheckBox и RadioButton как разные объекты с об щим предком и, соответственно, считает собственные методы этих объектов различными. CheckBox.CheckО
где CheckBox — логическое имя кнопка. Пример. Следующая строка кода выбирает вариант Meat из спис ка Toppings: Meat.CheckО RadioList.SeTectCsItem)
где RadioList — логическое имя списка параметров; sitem — выбирае мый параметр. Пример. Строка кода, выбирающая вариант large из списка Pizza Туре: Pi zzaType. Sel ect (" Large") Rational Robot RadioButton/CheckBox Click, recMethod$
где recMethocl$ — способ идентис{)ика11ии параметра. Пример. Следующая строка кода выбирает вариант Medium из спи ска Pizza Туре: RadioButton Click, •*Name=type:Index=2"
Пример. Строка кода для выбора варианта Meat из списка Top pings: CheckBox Click. "Jiaroe=iipeat-
Отмена выбранного параметра WinRunner button set (button, OFF)
где button — логическое имя или физическое описание кнопки. Пример. Следующая строка кода отменяет выбор параметра Large из списка вариантов Pizza Туре: button_set ("Large". OFF):
CheckBox/RadioButton
89
SilkTest
SilkTest из-за особенностей своей объектно-ориентированной архи тектуры рассматривает CheckBox и RadioButton как разные объекты с общим предком и считает собственные методы этих объектов различ ными. CheckBox.UncheckО
где CheckBox — логическое имя кнопки. Пример. Следующая строка кода отменяет выбор варианта Meat из списка Toppings: Meat.UncheckО RadioLi St. Select ( s i tern)
где RadioLi St — логическое имя списка параметров; si tern — выбирае мый параметр. Пример. Строка кода, выбирающая вариант Medium из списка Pizza Туре, отменяя тем самым предыдущий выбор: PizzaType.Select("Medium")
Rational Robot RadloButton/CheckBox Click, recMethod$
где recMethod$ ~ способ идентификации параметра. Пример. Следующая строка кода отменяет выбор варианта Mediuoi из списка Pizza Туре в результате повторного щелчка на его имени: Radi oButton CI i ск, '*Name=type; Index=2"
Пример. Строка кода для отмены выбранного варианта Meat из списка Toppings при повторном щелчке на его имени: CheckBox Click, "Name^meat"
Получение информации о состоянии элемента Button Иногда в ходе теста бывает необходимо узнать, активирован эле мент Button или нет, либо получить информацию о других свойствах элемента Button. Для этого используются следующие конструкции. WiftRunner buttoncheckstate (button.state)
где button — логическое имя или физическое описание кнопки; state — значение запрашиваемого состояния (ON или OFF).
90
Глава 4. Элементы интерфейса и их функции
Пример. Следующая строка кода проверяет, выбран ли в данный момент вариант Meat из списка Toppings: button_check_state ("Meat". ON); SilkTest
Из-за особенностей своей объектно-ориентированной архитектуры SilkTest рассматривает CheckBox и RadioButton как разные объекты с общим предком и, соответственно, считает собственные методы и свойства этих объектов различными. CheckBox.GetProperty(property)
где CheckBox — логическое имя кнопки; property — название запраши ваемого свойства. Пример. Следующая строка кода возвращает современное со стояние параметра Meat из списка Toppings: out^value « Meat.GetProperty("bValue") Radi oLi st.GetProperty(property)
где RadioList — логическое имя списка параметров; property — назва ние запрашиваемого свойства. Пример. Следующая строка кода возвращает выбранный в дан ный момент параметр из списка Pizza Туре: out__value = PizzaType.GetProperty("sValue") Rational Robot SQAGetProperty (recMethod$, property, outval ue)
где recMethodI — способ идентификации кнопки; property — название запрашиваемого свойства; out^value — переменная, хранящая значе ние запрашиваемого свойства. Пример. Следующая строка кода возвращает состояние парамет ра Meat из списка Toppings: SQAGetProperty( "Type- CheckBox;Name=meat". "State".out__va1 ue)
EditBox
щпштктштатттц Элсмент EditBox (Полс ввода) представляст собой осЩшттттттттт новной элемент получения текстовой информации от пользователя (элемент Textarea является частным случаем EditBox). По сути — это простая строка ввода, унаследованная из DOS и по лучившая своеобразный Windows-колорит. Ни для чего другого, кроме ввода текста, этот элемент не предназначен.
EditBox
91^
Какие же функции этого элемента необходимы для работы с ним? • Возможность ввода информации в поле. • Удаление элементов предыдущего ввода. • Получение текущего значения текста в поле ввода. Теперь на примере наиболее широко распространенных программ ных продуктов для автоматизации процессов тестирования рассмот рим, как эти функции реализованы.
Ввод информации в поле ввода WinRunner edit__set (edit.sValue)
где edit — логическое имя или физическое описание поля ввода; sValue — переменная, хранящая значение поля ввода, или непосред ственно поле ввода. Пример. Ввод строки «Пуа Vinnichenko» в EditBox Name: edit_,set ("Name", "Ilya Vinnichenko"): SilkTest TextField.Set(sValue)
где TextField — логическое имя поля ввода; sValue — переменная, хранящая значение поля ввода, или непосредственно поле. Пример. Ввод текста «Пуа Vinnichenko» в EditBox Name: Name.Set("nya Vinnichenko") Rational Robot
Из-за особенностей архитектуры Rational Robot не имеет возмож ности выполнить данную операцию в одной функции. В этом про граммном продукте ввод текста в поле разбит на два этапа: первый -щелкнуть в поле ввода, второй — набрать текст. 1. EditBox Click. recMethod$, где recMethodS - способ идентификации поля ввода. 2. InputKeys Keytextl, где Keytext$ — переменная, хранящая значение поля ввода, или непосредственно поле. Пример. Следующий блок кода вводит текст «Пуа Vinnichenko» в EditBox Name: EditBox Click, "Name«name", 'Xoords»91,12" InputKeys " Ilya Vinnichenko"
92
Глава 4. Элементы интеофейса и их функции
Возможность очистить эленмент от предыдущего ввода Иногда в процессе работы скрипта бывает необходимо очистить строку ввода от значения, переданного в предыдущих опергцпях с элементом. WinRunner e d i t s e t (edit.sValue)
где edit — логическое имя или физическое описание строки ввода; sValue — переменная, хранящая значение строки ввода, или непосред ственно строка ввода. Пример. Следующая строка впечатывает пустую строку в EditBox Name: edit^set ("Name". " " ) ; SilkTest TextFi eld.CIearText()
где TextFi eld — лошческое имя строки ввода. Пример. Следующая строка кода удаляет предыдущее значение из EditBox Name: Name.CIearTextО Rational Robot
Из-за особенностей своей архитектуры Rational Robot не имеет воз можности выполнить данную операцию в одной функции. В этом программном продукте ввод строки разбит на два шага: первый — щелкнуть на строке ввода, второй — набрать строку. 1. EditBox Click, recMethod$, где recHetbod$ — способ идентификации строки ввода. 2. InputKeys Keytext$, где Keytext$ — перех^нная, хранящая значение строки ввода, или непосредственно строка ввода. Пример. Следующая строка кода возвращает значение EditBox Name: EditBox Click. "Name=naroe", "Coords==91,12" InputKeys ""
Получение текущего значения в поле ввода WinRunner edit^gettext (edit.outvalue)
где edit — логическое имя или физическое описание поля ввода; out^value — переменная, возвращающая значение в поле ввода.
Table
93
Пример. Следующая cipoKa кода возвращает значение EditBox Name: ed1t_get_text ("Name*, out value): SiikTest TextField.GetlextO
где TextField — логическое имя поля ввода. Пример. Строка кода, возвращающая значение EditBox Name: out^value = Name.GetlextO Rational Robot SQAGetProperty{recMethod$,property,out^value)
где recMethod$ — способ идентификации поля ввода; property — на звание запрашиваемого свойства; <5ut value — переменная, хранящая значение запрашиваемого свойства. Пример. Следующая строка кода возвращает значение EditBox Name: 5t3/^tProperty( "Type* EditBox:Name*na!ne", "Text" .out^value)
Table Элемент Table (Таблица) представляет собой таблицу, хранящую дан ные, определяемые типом и особенностями конкретного приложения. Ячейки таблицы могут быть статическим (неизменяемым) текстом или представлять собой другие элементы (способные принимать вво димые пользователем данные), в частности, элемент EditBox. Необходимые функции этого элемента: • получение количества строк в таблице; • получение количества столбцов в таблице; • возврат значения заголовков таблицы; • возврат значения произвольной ячейки таблищл; • получение координаты произвольной ячейки таблицы по ее зна чению. Теперь рассмотрим, как эти функции реализованы, на примере про граммных продуктов.
Получение количества строк в таблице Функция используется для определения точного количества строк в таблице. Чаще всего применяется в тестах, рассчитанных на про верку данных, возвращаемых приложением.
94
Глава 4. Элементы интерфейса и их функции
WinRunner tb1_get_rows_count (table. out__value)
где table — логическое имя или физическое описание таблицы; out^value — переменная, содержащая возвращаемое значение. Пример. Следующая строка кода возвращает точное количество строк в таблице Order: tbl_get_rows__count ("Order", out__value); SilkTest Table.GetRowCountO
где Table — логическое имя таблицы. Пример. Строка кода, возвращающая точное количество строк в таблице Order: out^num - Order.GetRowCountO Rational Robot
Из-за особенности архитектуры Rational Robot не может выполнить данную операцию в одной функции. Для выполнения описанного действия необходимо написать функцию пользователя.
Получение количества столбцов в таблице Чаще всего применяется в тестах, рассчитанных на проверку возвра щаемых приложением данных. WinRunner tbl__get_cols__count (table, out^value)
где table — логическое имя или физическое описание таблицы; out_ value — переменная, содержащая возвращаемое значение элемента. Пример. Следующая строка кода возвращает точное количество столбцов в таблице Order: tbl^get^cols_count ("Order", out^value): SilkTest Table.GetColumnCount()
где Table — логическое имя таблицы. Пример. Строка кода, возвращающая точное количество столб цов в таблице Order: out num « Order. GetCol umnCount ()
Table
95
Rational Robot
Rational Robot не имеет возможности выполнить данную операцию в одной функции. Для выполнения описанного действия необходи мо написать функцию пользователя.
Возврат значений заголовков таблицы WinRunner
WinRunner предоставляет две функции для получения подобных дан ных: tbl_get_column__name (table, columnjndex, out^value) где table — логическое имя или физическое описание таблицы; column^index — порядковый номер столбца; out^value — переменная, содержащая возвращаемое значение элемента. Функция позволяет получить значение заголовка по его порядково му номеру. Пример. Следующая строка кода возвращает заголовок столбца № 2 в таблице Order: tbl_get_colunin_name ("Order", 2, out__value):
tbl_get_column_names (table, out_^value, out_num) где table — логическое имя или физическое описание таблицы; out^value — переменная, содержащая возвращаемые значения заголов ков таблицы; out^num — переменная, содержащая возвращаемое ко личество заголовков таблицы. Функция позволяет получить значения и количество заголовков таб лицы. Пример. Следующая строка кода возвращает значения и количе ство заголовков таблицы Order: tbl_get_column_names ("Order", o u t v a l u e , out^num);
SilkTest
SilkTest предоставляет функцию для получения значения конкрет ного заголовка по его порядковому номеру. В случае, когда необхо димо получить значения заголовков таблицы, эту функцию следует использовать несколько раз. Tabl е. GetCol umnName (col unin_i ndex)
где Tabl e — логическое имя таблицы. col umn^i ndex — порядковый номер столбца.
96
Глава 4. Элементы интерфейса и их функции
Пример. Следующая строка кода возвращает заголовок столбца № 2 в таблице Order: out__value = Order.GetColumnName(2)
Пример. Следующий блок кода возвращает заголовки столбцов № 2 и 3 в таблице Order: outvaluel = 0rder.GetColLimnName(2) out_value2 = Order. GetColumnNameO) Rational Robot
Из-за особенностей своей архитектуры Rational Robot не имеет воз можности выполнить данную операцию в одной функции. Для вы полнения описанного действия необходимо написать функцию поль зователя.
Получение значения произвольной ячейки таблицы Чаще всего применяется в тестах, рассчиганньх на проверку возвра щаемых приложением данных. WinRunner
t b l g e t c e l l d a t a (table, row. column, out value) где table — логическое имя или физическое описание таблицы; row — номер строки, в которой находится выбираемая ячейка; col umn — но мер столбца, в котором находится выбираемая ячейка; outvalue — переменная, содержащая возвращаемое значение элемента. Пример. Следующая строка кода возвращает точное значение ячейки с координатами: 2-я строка, 3-й столбец таблицы Order: tbl_get^cell_data ("Order". "#2"/'#3\
out_value):
Silkiest Table.GetCellValue(sCell)
где Table — логическое имя таблицы; sCell — координаты ячейки, вы раженные через тип данных TABLECELL. Пример. Строка кода, возвращающая точное значение ячейки с ко ординатами: 2-я строка, 3-й столбец таблицы Order: TABLECELL sCell = { " 2 \ " 3 " } out ПШ1« Order.GetCelIValueCsCel 1)
Scroll
97
Rational Robot
Для выполнения описанного действия необходимо написать функ цию пользователя.
Получение координаты произвольной ячейки таблицы по ее значению Чаще всего применяется в тестах, рассчитанных на проверку возвра щаемых приложением данных. WinRunner
Для выполнения описанного действия необходимо написать функ цию пользователя. SilkTest Table.FindCell (sValue)
где Table — логическое имя таблицы; sValue — значение ячейкР!. Пример. Следующая строка кода возвращает координаты ячейки со значением Pepperom* в таблице Order: out_value = Order.FindCell (sValue) Rational Robot
Для выполнения этого действия необходимо написать функцию пользователя.
Scroll Элемент Scroll (Ползунок) — предоставляет возможность 21 перемещаться из одного места окна/документа в другое. Ползунок незаменим для приложений обработки текста, а также для приложений, в которых количество управляющих элементов невоз можно разместить в пределах видимости одного окна. Необходимые функции этого элемента. • Перемещение в начало окна/документа. • Перемещение в конец окна/документа. • Перемещение на фиксированное расстояние внутри окна/доку мента. • Перемещение на один экран/страницу выше/ниже.
98
Глава 4. Элементы интерфейса и их функции
Рассмотрим, как эти функции реализованы на примере рассматри ваемых программных продуктов.
Перемещение в начало окна/документа WinRunner scron_min (scroll.orientation)
где scroll — логическое имя или физическое описание ползунка; orientation — направление движения ползунка: HSCROLL (горизонталь ное) и VSCROLL (вертикальное). Пример. Следующая строка кода перемещает ползунок в старто вую позицию по вертикали: scroll_min ("ScrollBar", VSCROLL): SiikTest ScrollBar.ScrollToMinO
где ScrollBar — логическое имя ползунка. Пример. Следующая строка кода перемещает ползунок в старто вую позицию: ScrollBar.ScrollToMinO Rational Robot
ScrollBar OrientationFunction, recMethocl$, Position где OrientationFunction — направление движения ползунка: HScrollTo (горизонтальное) и VScrollTo (вертикальное); recMethodS — способ идентификации ползунка; Position — координаты ползунка (О — стар товая позиция, конечная позиция зависит от объекта). Пример. Следующая строка кода перемещает ползунок в старто вую позицию по вертикали: ScrollBar VScrollTo. "ObjectInclex=l", "Position=0"
Перемещение в конец окна/документа WinRunner scroll_max(scroll.orientation)
где scroll — логическое имя или физическое описание ползунка; orientation — направление Движения ползунка: HSCROLL (горизон тальное) и VSCROLL (вертикальное). Пример. Следующая строка кода перемещает ползунок в конеч ную позицию по горизонтали: scroll max ("ScrollBar". HSCROLL);
Scroll
99
SilkTest Scroll Bar.ScrollToMax()
где Scroll Bar — логическое имя ползунка. Пример. Следующая строка кода перемещает ползунок в конеч ную позицию: Scroll Ваг. ScrollToMaxO Rational Robot
Scroll Ваг OrientationFunction, recMethod$. Position где OrientationFunction — направление движения ползунка: HScroliTo (горизонтальное) и VScrollTo (вертикальное); recMethod$ — способ идентификации ползунка; Position — координаты ползунка (О — стар товая позиция, конечная позиция зависит от объекта). Пример. Строка кода, перемещающая ползунок в конечную по зицию по горизонтали: Scroll Ваг HScroliTo, "ObjectIndex=l", "Position=159"
Перемещение на фиксированное расстояние внутри окна документа WinRunner scrollJineCscroll,orientation.lines)
где scroll — логическое имя или физическое описание ползунка; orientation — направление движения ползунка: HSCROLL (горизон тальное) и VSCROLL (вертикальное); lines — количество линий, на ко торое происходит перемещение: «+» — вниз/вправо, «-» — вверх/ влево. Пример. Следующая строка кода перемещает ползунок на 10 ли ний вправо по горизонтали: scroll J ine ("ScrollBar". HSCROLL. 10):
SilkTest, Scrol1 Bar.ScrollByLine(lines)
где ScrollBar — логическое имя ползунка; lines — количество линий, на которое происходит перемещение: «+» — вниз/вправо, «-» — вверх/влево. Пример. Перемещение ползунка на 10 линий вниз/вправо: Scrol1 Bar.Scrol1ByLi ne(10)
100
Глава 4. Элементы интерфейса и их функции
Rational Robot Scroll Ваг OrientationFunction, recMethodS
где OrientationFunction ~ направление движения ползунка: • Scroll Right — на одну линию вправо; • Scrol 1 Left — на одну линию влево; • Scroll Li neUp — на одну линию вверх; • Scroll Li neDown — на одну линию вниз; • recMethodS — способ идентификации ползунка. Пример. Перемещение ползунка на одну линию вниз: Scroll Ваг Scroll Li neDown. "ObjectIndex=l"
Перемещение на одну страницу/экран выше/ниже Функция используется для быстрой навигации внутри окна/доку мента. WinRunner scroll_page(scrol1,orientation,pages)
где scroll — логическое имя или физическое onpicanne ползунка; orientation — направление движения ползунка: HSCROLL (горизонталь ное) и VSCROLL (вертикальное); lines — количество линий, на которое происходит перемещение: «+» — вниз/вправо, «-» — вверх/влево. Пример. Перемещение ползунка на одну страницу/экран вверх по вертикали: scroll_page ("ScrollBar". VSCROLL,-1); SilkTest Scroll Ваг.ScrolIByPage(pages)
где ScrollBar — логическое имя ползунка; pages — количество линий, на которое происходит перемещение: «+» — вниз/вправо, «-» — вверх/влево. Пример. Перемещение ползунка на одну страницу/экран вверх/ влево. Scroll Ваг.ScrolIByPage(-l) Rational Robot ScrollBar OrientationFunction, recMethod$
где OrientationFunction — направление движения ползунка:
Tab
101
• ScrollPageRight — на одну страницу/экран вправо; • Scrol 1 PageLeft — на одну страницу/экран влево; • Scrol 1 PageUp — на одну страш1цу/экран вверх; • Scrol 1 PageDown — на одну страницу/экран вниз; recMethodS — способ идентифргкации ползунка. Пример. Следующая строка кода перемещает ползунок на одну страницу/экран вверх. ScrollBar ScrollPageUp, "ObjectIndex=l"
Tab Элемент Tab (Вкладка) внешне напомршает папку для фай |Т«Ь2 I лов. Причина очень проста — он изначально разрабатывал ся в качестве электронной «замены» подобной папки. Основная среда его применения — приложения, отображающие большое количество элементов без использованргя дополнительных окон. В этом случае элементы группируются и каждая группа помещается в свою «папку». Функции этого элемента, необходимые в работе с ним. • Перемещение от одного элемента Tab к другому по его значению. • Получение количество вкладок, содержащихся в Tab. • Перемещение от одного элемента Tab к другому по его порядково му номеру. Теперь на примере программных продуктов для автоматизации про цессов тестирования посмотрим, как эти элементы реализованы.
Перемещение от одного элемента Tab к другому по его значению Функция используется для навигации между различными вкладка ми, когда скрипт работает с объектами, расположенными на различ ных вкладках. WinRunner tab_select_item (tab.item)
где tab — логическое имя или физическое описание элемента Tab; item -- переменная, содержащая значение выбираемой вкладки. Пример. Перемещение на выбираемую вкладку: tab select item ("TabControl", "Tabl");
102
Глава 4. Элементы интерфейса и их функции
SilkTest PageLi st.Select(sValue
где PageLi St — логическое имя элемента Tab; sValue — переменная, содержащая значение выбираемой вкладки. Пример. Перемещение на выбираемую вкладку: TabControl.SelectCTabl") Rational Robot TabControl Click, recMethod$, Coords$,
где recMethod$ — способ идентификации элемента Tab; Coords — х- и yкоординаты вкладки. Пример. Перемещение на выбираемую закладку: TabControl Click. "ObjectIndex=l:\;ItemText=Tabl\ "Coords=50,25"
Получение количества вкладок, содержащихся в Tab WinRunner tab_get__info (tab, "count",out__value
где tab — логическое имя или физическое описание элемента Tab; out^value ~ переменная, содержащая количество вкладок в элементе. Пример. Следующая строка кода возвращает количество вкладок в элементе: tab_getJnfo ("TabControl". "count". out__value); SilkTest PageLi st.GetPageCount()
где PageLi st — логическое имя Tab. Пример. Строка кода, возвращающая количество вкладок в эле менте: out__value « TabControl .GetPageCountО Rational Robot SQAGetProperty( recMethocl$, property. out_val ue)
где recMethod$ — способ идентификации строки ввода; property — на звание запрашиваемого свойства; out__value — переменная, хранящая значение запрашиваемого свойства. Пример. Следующая строка кода возвращает количество вкладок в элементе: S(JAGetProperty("Type=TabControl:ObjectIndex»l"."ItemCount".out_value)
Label
103
Перемещение от одного элемента Tab к другому по его порядковому номеру Функция используется для навигации между различными вкладка ми. В отличие от предыдущей функции, здесь используется поряд ковый номер вкладки. WinRunner tab_se1ect_item (tab,item)
где tab — логическое имя или физическое описание элемента Tab; item — переменная, содержащая номер выбираемой вкладки. Пример. Перемещение на выбираемую вкладку: tab__select_item ("TabControl". "#0"); SiikTest PageLi st.Select(sVal ue)
где PageLi St — логическое имя элемента Tab; sValue — переменная, содержащая номер выбираемой вкладки. Пример. Перемещение на выбираемую вкладку: TabControl.Select("#1") Rational Robot TabControl Click. recMethod$, Coords$
где recMethod$ — способ идентификации элемента Tab; Coords — х- иукоординаты вкладки. Пример. Перемещение на выбираемую вкладку: TabControl Click. "ObjectIndex=l:\;ItemIndex=l". "Coords=50.25"
Label Элемент Label (Метка) представляет собой обыкновенный •••-t^t^V.r статический текст. Используется для создания сообщений и объяснений. Сообщения выводятся внутри диалоговых окон, а объ яснения, как правило, — слева от управляющего элемента. По сути, единственная функция этого элемента — получение инфор мацию о воспроизведенном тексте. Далее рассмотрим, как эта функция реализована.
104
Глава 4. Элементы интерфейса и их функции
WinRunner static_get_text (static.out_value)
где static — логическое имя или физическое описание статического текста; out_va1ue — переменная, получающая возвращаемое значение строки ввода. Пример. Следующая строка кода возвращает значение элемента Name: static_get_text ("Name", out_value); Silkiest Stati cText.GetText()
где StaticText — логическое имя статического текста. Пример. Возвращение значения элемента Name: out_va1ue = Name. GetText О Rational Robot SQAGetProperty(recMethodS,property,out_va1ue)
где recMethocl$ — способ идентификации строки ввода; property — на звание запрашиваемого свойства; out_va1ue — переменная, хранящая значение запрашиваемого свойства. Пример. Следующая строка кода возвращает значение элемента Name: SQAGetProperty( "Туре= Label: ID=1". "Text".out_va1 ue)
Image button Элемент Image button (Вставка изображения) представляет собой один из двух управляю щих элементов, использующихся только в сре де Веб (ранее речь шла о Win32). По своей m*fi**' сути этот он сходен с элементом Button и отличается только внеш ним видом (в среде Веб это обыкновенный растровый рисунок). Но это касается лишь «пользовательской» стороны. Его внутренняя, «программистская», начинка сильно отличается от «начинки» эле мента Button. По сути, единственная функция этого элемента — возможность щелкнуть на интерактивной кнопке. Рассмотрим, как эта функция реализована.
Link
105
WinRunner webimageclick (link, x,y)
где link — логическое имя или физическое описание кнопки; х и у ~ х- и ^/-координаты объекта. Пример. Следующая строка кода «задает щелчок» на кнопке Buck: web_image_c1ick ("Buck",47.28):
SilkTest HTMLImage.ClickRegion(sRegion)
где HTMLImage — логическое имя кнопки; sRegion — переменная, со держащая описание области кнопки. Пример. Следующая строка кода задает щелчок на кнопке Buck: Buck.ClickRegionC'Buck. jpg")
Rational Robot HTMLImage Click, recMethod$, Coords$
где recMethodS — способ идентификации ссылки; Coords — х- и у-координаты объекта. Пример. Щелчок на кнопке Buck: HTMLImage Click. "Type=HTMLImage:HTMLId=l", "Coords=47.28"
Link Элемент Link (Ссылка) — второй из управляющих [email protected] элементов, использующихся только в среде Веб. По сути, этот элемент является «дверью», ведущей на другую стра ницу или в другую часть той же страницы. Рассмотрим, как эта функция реализована. WinRunner webjink_c1ick (link)
где link — логическое имя или физическое описание ссылки. Пример. Следующая строка кода задает переход по ссылке [email protected]: web_l i n k c l i ск (" someone@somesi te. com") :
SilkTest HTMLLink.ClickO
где Html Link — логическое имя ссылки.
106
Глава 4. Элементы интерфейса и их функции
Пример. Переход по ссылке [email protected]: MailLink.ClickO Rational Robot HTMLLink Click, recMethod$
где recMethod$ — способ идентификации ссылки. Пример. Переход по ссылке [email protected]: HTMLLink C l i c k . "Type=HTMLLink;[email protected]"
На этом описание основных элементов интерфейса пользователя и функций работы с ними закончено. Перейдем к работе со вспомо гательными функциями.
Глава 5 Вспомогательные функции
в этой главе разговор пойдет о так называемых вспомогательных функциях. Какие же функции называются вспомогательными и по чему? Во-первых, функция относится к вспомогательным тогда, ко гда она используется всеми элементами графического интерфейса пользователя и при этом не зависит от какого-либо элемента графи ческого интерфейса. Во-вторых, вспомогательными будем называть функции, выполняющие «техобслуживание», например, функции работы с системой. Прежде чем вести более детальный разговор, сгруппируем вспомогательные функции следующим образом: • Функции имитации клавиатурного ввода. • Функции имитации действий, выполняемых мышью. • Функции работы с системой. • Функции оповещения о результатах. • Функции синхронизации. • Функции проверки существования объекта. • Функции работы с файлами.
Функции имитации клавиатурного ввода Функции имитации клавиатурного ввода, как и следует из назва ния, имитируют пользовательский ввод с клавиатуры. «Тогда поче му функции, а не функцил?» — спросите вы. — «Ведь функция не должна меняться в зависимости от того, какая клавиша и когда была нажата. Верно?» Не совсем. К сожалению — или к счастью, тут уж
108
Глава 5. Вспомогательные функции
вам решать — программные продукты, представленные сегодня на рынке, предоставляют более чем одну функцию для такор!, казалось бы, простой вещи, как имитация пользовательского ввода. Поэтому изменив уже ставшему привычным сценарию, мы не пойдем от об щего к частному, а перейдем сразу на «личности».
WinRunner Mercury Interactive решила предоставить пользователю две функции имитации пользовательского ввода: typeO и obj_type(). Чем же они отличаются? Разница в том, что при использовании функции typeO клавиатурный ввод посылается просто обработчику событий Win dows, тогда как при использовании функции obj_type() клавиатур ный ввод посылается непосредственно указанному объекту. Давайте более детально рассмотрим эти функции на практических примерах. type (keyboardinput)
где keyboard^input — строка, описывающая клавиатурный ввод. Обо значение функциональных клаврпи, таких как Ctrl, Shift, Alt и т. д., должно начинаться знаком < и оканчиваться знаком >. Пример. Следующая строка кода имитирует нажатие клавиши F1 и, соответственно, вызов Help: type (""); obj^type (object. keyboard_input)
где object — объект, которому передается пользовательский клавиа турный ввод; keyboard_input — строка, описывающая клавиатурный ввод. Обозначение функциональных клавиш, таких как Ctrl, Shift, Alt и т. д., должно начинаться знаком < и оканчиваться знаком >. Пример. Следующая строка кода имитирует введение значения Пуа Vinnichenko в элемент Name класса EditBox. Эта строка кода аналогична использованию функции edit^setO: o b j t y p e ("Name", "Пуа Vinnichenko");
SilkTest в отличие от Mercury Interactive, Segue решила предоставить поль зователю всего одну функцию, а вернее сказать, метод имитации пользовательского ввода: TypeKeysO. Создатели SilkTest, справедли во рассудили, что имея объектно-ориентированную архитектуру, а не процедурную, как у WinRunner, достаточно будет создать лишь один метод. Различные задачи будут решаться в зависимости от того, из
функции имитации клавиатурного ввода
109
какого объекта будет запрашиваться метод. Рассмотрим этот метод более детально на практических примерах, чтобы определить сферу его применения. Object.TypeKeys (keyboard^input)
где Object — объект, которому передается пользовательский клавиа турный ввод; keyboard^input — строка, описывающая клавиатурный ввод. Обозначение функциональных клавиш, таких как Ctrl, Shift, Alt и т. д., должно начинаться знаком < и оканчиваться знаком >. Пример. Следующая строка кода имитирует нажатие клавиши F1 и, соответственно, вызов Help: Browser.TypeKeys ("")
Пример. Следующая строка кода имитирует введение значения Uya Vinnichenko в элсхмент Name класса EditBox. Эта строка кода аналогична использованию метода SetTextO: Name.TypeKeys ("Пуа Vinnichenko")
Следует также отметить наличие методов PressKeys PI ReleaseKeys. В отличие от метода TypeKeys они не являются в полном смысле ме тодами имитации пользовательского ввода. Это низкоуровневые ме тоды, призванные решить задачу удержания кнопки в нажатом состоя нии в течение определенного времени. При этом могут выполняться другие действия. Лучшим примером использования этого блока яв ляется имитация ситуации, когда пользователь щелкает на несколь ких объектах, удерживая клавишу Ctrl нажатой. Object.PressKeys (keyboard_input)
где Object — объект, которому передается пользовательский клавиа турный ввод; keyboard^input — строка, описывающая клавиатурный ввод. Обозначение функциональных клавиш, таких как Ctrl, Shift, Alt и т. д., должно начинаться знаком < и оканчиваться знаком >. Object.ReleaseKeys (keyboard_i nput)
где Object — объект, которому передается пользовательский клавиа турный ввод; keyboardinput — строка, описывающая клавиатурный ввод. Обозначение функциональных клавиш, таких как Ctrl, Shift, Alt и т. д., должно начинаться знаком < и оканчиваться знаком >. Пример. Следующий блок кода имитирует введение значения ilya vinnichenko в элемент Name класса EditBox к а к ILYA VINNICHENKO: Name.PressKeys("<Shi ft>") Name.TypeKeys ("ilya vinnichenko") Name.ReleaseKeys("<Shi ft>")
110
Глава 5. Вспомогательные функции
Rational Robot Rational, разработав архитектуру, базирующуюся на событиях, ре шила пойти путем, отличным от того, которым пошли Mercury In teractive и Segue. Rational Robot предоставляет пользователю две функции имитации пользовательского ввода: InputKeys и InputChars. Различие этих функций состоит в том, что InputKeys передает объек ту в фокусе непосредственно значения клавиш, тогда как InputChars передает любое значение как строку. В исполнении InputKeys F1 — это функциональная клавиша вызова Help, а в исполнении InputChars — это просто строка со значением F1. Рассмотрим эти функции более детально на практических примерах. InputKeys keytext$
где keytext$ — строка, описываюш[ая клавиатурный ввод. Обозначе ние функциональных клавиш, таких как Ctrl, Shift, Alt и т. д., должно начинаться знаком { и оканчиваться знаком }. Пример. Следующая строка кода имитирует нажатие клавиши F1 и, соответственно, вызов Help: InputKeys "{Fl}"
InputChars keytext$
где keytext$ — строка, описывающая клавиатурный ввод. Пример. Следующий блок кода имитирует введение значения Пуа Vinnichenko в элемент Name класса EditBox: EditBox Click, "Name=name". "Coords=91,12" InputChars " Ilya Vinnichenko"
Функциональные клавиши и их значения приведены в таблице. Клавиша
WinRunner
Silkiest
Rational Robot
F1
kF1
F1
F1
F2
kF2
F2
F2
F3
kF3
F3
F3
F4
kF4
F4
F4
F5
kF5
F5
F5
F6
kF6
F6
F6
F7
kF7
F7
F7
F8
kF8
F8
F8
F9
kF9
F9
F9
111
функции имитации действий, выполняемых мышью
Клавиша
WinRunner
F10 F11 F12
Silkiest
Rational Robot
kF10
F10
F10
kF11
F11
F11
kF12
F12
F12
Esc
kEsc
Esc
Esc
Enter
kReturn
Enter
Enter
Shift
kShift_L/kShlft_R
LeftShift/RightShift
LeftShlft/RightShift
Alt
kAlt_L/kAlt_R
LeftAlt/RightAlt
LeftAlt/RightAlt
Ctrl
kCtrLL/kCtrLR
LeftCtrl/RlghtCtrl
LeftCtrl/RightCtrl
Insert
klns_E
Insert
Insert
Honne
kHome_E
Home
Home
Delete
kDel.E
Delete
Delete
Page Up
kPgUp.E
PgUp
PgUp
Page Down
kPgDn_E
PgDn
PgDn
End
kEnd_E
End
End
Up
kUp_E
Up
Up
Down
kDown^E
Down
Down
Left
kLeft_E
Left
Left
Right
kRight_E
Right
Right
Backspace
kBackSpace
Backspace
Backspace
Функции имитации действий, выполняемых мышью Эти функции имитируют работу пользователя с мышью. Во многом они сходны с функциями из предыдущей группы, но вместе с тем налицо ряд существенных отличий. Во-первых, у мыши три кнопки (да-да, именно три), и в зависимости от того, какая из них была на жата, реакция тестируемого приложения будет различной. Во-вто рых, чтобы сымитировать щелчок мышью, нужно знать координаты (в пикселах относительно верхнего левого угла экрана или активно го окна, всегда имеющего координаты [О, 0]) того места или объекта, где щелчок будет произведен. Поэтому, как и в предыдущем случае, перейдем сразу на «личности».
112
Глава 5. Вспомогательные функции
WinRunner Mercury Interactive решила предоставить пользователю целых шесть функций имитации пользовательского ввода: clickO, dblclickO, obj_click(), obj__mouse_click(), obj_mouse_dbl_click(), win_mouse_click() и win_mouse_dbl_c1ick(). По сути их можно разделить на две катего рии: одиночный щелчок (clickO, objmouseclickO, winjnouse_click()) и двойной щелчок (dbl_click(), objmousedbl clickO, winjnouse_db1_ clickO). Внутри каждой категории функции различаются только объектами, с которыми они работают. Рассмотрим эти функции бо лее детально на практических примерах. c l i c k (button)
где button — кнопка мыши, использующаяся для щелчка, может быть Left, Right или Middle.
Пример. Следующая строка кода имитирует щелчок правой кноп кой мыши: c l i c k ("Right"): dbl_click (button)
где button — кнопка мыши, использующаяся для щелчка, может быть Left, Right или Middle.
Пример. Имитация двойного щелчка левой кнопкой мыши: dbl_click ( " L e f t " ) ; obj_mouse_click (object, x, y [ , button])
где object — объект, которому передается пользовательский щелчок мыши; X и у — координаты области внутри объекта, на которой будет сделан щелчок; button — кнопка мыши, использующаяся для щелч ка, может быть Left, Right или Middle (необязательный параметр, Left по умолчанию). Пример. Следующая строка кода имитирует щелчок правой кноп кой мыши на элементе Name класса EditBox: obj_mouse_click ("Name", 10. 10. "Right"); obj_mouse__dbl__click (object, x. y [ . button])
где object — объект, которому передается пользовательский щелчок мыши; X и у — координаты области внутри объекта, на которой бу дет сделан щелчок; button — кнопка мыши, использующаяся для щелчка, может быть Left, Right или Middle (необязательный пара метр, Left по умолчанию).
функции имитации действий, выполняемых мышью
113
Пример. Имитация двойного щелчка левой кнопкой мыши на элементе Name класса EditBox: obj_mouse_db1_c1ick ("Name". 10, 10):
win_mouse_c1ick (window, x, y[, button, modifier]) где window — окно, которому передается пользовательский щелчок мыши; X и у — координаты области внутри окна, на которой будет сделан щелчок; button — кнопка мыши, использующаяся для щелч ка, может быть Left, Right или Middle (необязательный параметр. Left по умолчанию); modifier — клавиша, удерживаемая нажатой при щелч ке, может быть CONTROL, SHIFT или CONTROL_SHIFT (необязательный па раметр, null по умолчанию). Пример. Следующая строка кода имитирует щелчок правой кноп кой мыши на окне PizzaOrder при нажатой клавише Ctrl: win_mouse_click ("PizzaOrder", 10, 10, "Right", "CONTROL");
winmousedbl click (window, x, y[, button, modifier]) где window — окно, которому передается пользовательский щелчок мыши; X и у — координаты области внутри окна, на которой будет сделан щелчок; button — кнопка мыши, использующаяся для щелч ка, может быть Left, Right или Middle (необязательный параметр. Left по умолчанию); modifier — клавиша, удерживаемая нажатой при щелчке, может быть CONTROL, SHIFT или CONTROL_SHIFT (необязатель ный параметр, null по умолчанию). Пример. Следующая строка кода имитирует двойной щелчок ле вой кнопкой мыши на окне PizzaOrder: win_mouse_dbl click ("PizzaOrder", 10, 10);
SilkTest в отличие от Mercury Interactive, Segue предоставляет три метода ими тации пользовательского ввода: ClickO, DoubleClickO и MultiClickO. Создатели SilkTest справедливо рассудили, что имея объектно-ори ентированную архитектуру, а не процедурную, как у WinRunner, достаточно будет лишь определить нужные методы в классе AnyWin, являющемся родительским по отношению ко всем остальным элемен там пользовательского интерфейса. Различные задачи будут решать ся в зависимости от того, из какого объекта запрашивается метод. Рассмотрим эти методы более детально на практических примерах, чтобы увидеть сферу их применения.
114
Глава 5. Вспомогательные функции
Object.Click ([button.х.у])
где Object — объект, которому передается пользовательский щелчок мыши; button — кнопка мыши, использующаяся для щелчка, может быть 1 (Left), 2 (Right) или 3 (Middle) (необязательный параметр, по умолчанию 1); х и у — координаты области внутри объекта, в кото рой будет сделан щелчок (необязательный параметр). Пример. Следующая строка кода имитирует щелчок правой кноп кой мыши на элементе Name класса EditBox: Name.Click (2) Object.Doubleclick ([button, x, y])
где Object — объект, которому передается пользовательский щелчок мыши; button — кнопка мыши, использующаяся для щелчка, может быть 1 (Left), 2 (Right) или 3 (Middle) (необязательный параметр, по умолчанию 1); X и у — координаты области внутри объекта, на кото рой будет сделан щелчок (необязательный параметр). Пример. Следующая строка кода имитирует двойной щелчок ле вой кнопкой мыши на окне PizzaOrder: PizzaOrder.Doubleclick О Object.MultiClick (count[, button, x, y])
где Object — объект, которому передается пользовательский щел чок мыши; count — количество щелчков мыши; button — кнопка мыши, использующаяся для щелчка, может быть 1 (Left), 2 (Right) или 3 (Middle) (необязательный параметр, по умолчанию 1); х и у — координаты области внутри объекта, на которой будет сделан щел чок (необязательный параметр). Пример. Тройной щелчок левой кнопкой мыши на окне PizzaOrder: PizzaOrder.MultiClick (3. 1)
Rational Robot Rational, разработав архитектуру, базирующуюся на событиях, по шла своим путем. Rational Robot предоставляет пользователю 48 различных способов щелчка мыши. Рассмотрим эти функции более детально. Object MouseAction recType$
где Object — объект, которому передается пользовательский щелчок мыши; гесТуре$ — способ определения объекта; MouseAction — вид щелчка мыши:
функции имитации действий, выполняемых мышью
115
Click — левой кнопкой; Middle^Click — средней кнопкой; Right__Click — правой кнопкой; Shift__Click — левой кнопкой, при нажатой клавише Shift; Shift_Middle_Click — средней кнопкой, при нажатой клавише Shift; Shift_Right_Click — правой кнопкой, при нажатой клавише Shift; Ctrl_Click — левой кнопкой, при нажатой клавише Ctrl; Ctrl_Middle_Click — средней кнопкой, при нажатой клавише Ctrl; Ctrl_Right__Click — правой кнопкой, при нажатой клавише Ctrl; Alt__Click — левой кнопкой, при нажатой клавише Alt; Alt_Middle__Click — средней кнопкой, при нажатой клавише Alt; Alt_Right__Click — правой кнопкой, при нажатой клавише Alt; ShiftCtrl^Click ~ левой кнопкой, при нажатых клавишах Shift+Ctrl; ShiftCtrl_Middle_Click — средней кнопкой, при нажатых клавишах Shift+Ctrl; ShiftCtrl_Right_Click — правой кнопкой, при нажатых клавишах Shift+Ctrl; ShiftAlt_Click — левой кнопкой, при нажатых клавишах Shift+Alt; ShiftAlt_Middle_Click — средней кнопкой, при нажатых клавишах Shift+Alt; ShiftAlt_Right_Click — правой кнопкой, при нажатых клавишах Shift+Alt; CtrlAlt_Click — левой кнопкой, при нажатых клавишах Ctrl+Alt; CtrlAlt^MiddleClick — средней кнопкой, при нажатых клавишах Ctrl+Alt; CtrlAlt_Right Click — правой кнопкой, при нажатых клавишах Ctrl+Alt; ShiftCtrlAltClick — левой кнопкой, при нажатых клавишах Shift+Ctrl+Alt; ShiftCtrlAlt_Middle_Click — средней кнопкой, при нажатых клави шах Shift+Ctrl+Alt; ShiftCtrlAlt_Right_Click — правой кнопкой, при нажатых клави шах Shift+Ctrl+Alt; DblClick — двойной, левой кнопкой; Middle^DblClick — двойной, средней кнопкой;
116
Глава 5. Вспомогательные функции
• Right_Db1 Click — двойной, правой кнопкой; • Shift_Db1 Click — двойной, левой кнопкой, при нажатой клавише Shift; • Shi ftMiddleDbl Click — двойной, средней кнопкой, при нажатой клавише Shift; • Shift_Right_DblClick ~ двойной, правой кнопкой, при нажатой клавише Shift; • Ctrl_DblClick — двойной, левой кнопкой, при нажатой клавише Ctrl; • CtrlJ1icldle_DblClick — двойной, средней кнопкой, при нажатой клавише Ctrl; • Ctrl_Right_DblClick — двойной, правой кнопкой, при нажатой кла више Ctrl; • А1 t^DblCl ick — двойной, левоР! кнопкой, при нажатой клавише Alt; • Alt_Middle_DblClick — двойной, среднер! кнопкой, при нажатой клавише Alt; • Alt_Right_DblClick — двойной, правой кнопкой, при нажатой кла више Alt; • ShiftCtrlDblCl ick — двойной, левой кнопкой!, при нажатых клави шах Shift+Ctrl; • ShiftCtrl_Middle_DblClick — двойной, средней кнопкой, при нажа тых клавишах Shift+Ctrl; • ShiftCtrlRightDblCl ick — двойной, правой кнопкой, при нажатых клавишах Shift+Ctrl; • ShiftAlt_DblClick — двойной, левой кнопкой, при нажатых клави шах Shift+Alt; • Shi ftAltMiddleDbl Click — двойной, средней кнопкой, при нажа тых клавишах Shift+Alt; • ShiftAlt_Right_DblClick — двойной, правой кнопкой, при нажатых клавишах Shift+Alt; • CtrlAltDblClick — двойной, левой кнопкой, при нажатых клави шах Ctrl+Alt; • CtrlAlt_Middle_DblClick — двойной, средней кнопкой, при нажатых клавишах Ctrl+Alt; • Ctrl AltRightDbl Click — двойной, правой кнопкой, при нажатых клавишах Ctrl+Alt;
функции работы с системой
117
Shi ftCtrlAUDbl Click — двойной, левой кнопкой, при нажатых кла вишах Shift+Ctrl+Alt; ShiftCtrlAU_Middle_DblC1ick — двойной, средней кнопкой, при на жатых клавишах Shift+Ctrl+Alt; ShiftCtr1Alt_Right_DblClick — двор1ной, правой кнопкой, при нажа тых клавишах Shift+Ctrl+Alt. Пример. Имитация щелчка правой кнопкой мыши на элементе Name класса EditBox. EditBox Right_Click, "Name=name". "Coords=91,12"
Функции работы с системой При автоматизации процессов тестирования иногда возникает ситуа ция, когда нужно запустить дополнительное приложение или выпол нить DOS-команду прямо из тела скрипта. Именно для таких случаев и была разработана группа функций работы с системой. По большо му счету, их можно свести к двум типам: • Запуск нового приложения; • Выполнение DOS-команды. У каждого из производителей программных продуктов для автома тизации процессов тестирования имеется свое видение программ ных решенш! подобных задач, поэтому мы в который раз переходим сразу на «личности».
WinRunner Mercury Interactive предоставляет две функции работы с системой: invoke_application() и dos_sy$tem(). Разница между ними в том, что первая используется только для запуска приложений, тогда как вто рая -- для выполнения командных строк DOS. Рассмотрим эти функ ции более детально. invoke_application (file, command_option. working_dir, show) где file — полный путь и имя программы; command_option ~ парамет ры командной строки; working_dir — путь по умолчанию для запус каемой программы; show — определитель внешнего вида окна откры ваемой программы, может быть следующим: • SWHIDE — скрывает окно за уже открытым окном и активирует его; • SW MINIMIZE — сворачивает окно и активирует верхнее окно;
118
• • • • • • • •
Глава 5. Вспомогательные функции
SW_RESTORE — активирует окно и помещает его поверх остальных; SW_SHOW — активирует окно в положении по умолчанию; SW_SHOWMAXIMIZED — активирует окно и разворачивает его; SW_SHOWMINIMIZED — активирует окно и сворачивает его; SW_SHOWMINNOACTIVE — сворачивает окно и активирует предыдущее окно; SW_SHOWNA — восстанавливает окно в положение по умолчанию и активирует предыдущее окно; SW_SHOWNOACTIVATE — восстанавливает окно в том виде, в котором оно было вызвано последний раз, и активирует предыдущее окно; SWSHOWNORMAL — активирует окно в положении по умолчанию. Пример. Следующая строка кода открывает Notepad: invoke_app1ication( "notepad","", "CiWTEXT" ,SW_SHOWMINIMIZED)
dos_system (expression)
где expression — командная строка DOS. Пример. Следующая строка кода открывает autoexec.bat при по мощи Notepad: dos^system ("notepad c:\autoexec.bat");
SiikTest Segue имеет целый арсенал средств работы с системой. Это два ме тода окна MainWin: Start О и InvokeO, и 39 функций: SYS^CompareBinary; SYS_CompareBitmap; SYS_CompareText; SYSCopyFile; SYS_DirExists; SYS_Execute; SYSJileExists; SYS_(3etB1tmapCRC; SYS_GetDir; SYS_(5etDirContents; SYS_GetDrive; SYS_GetEnv; SYS_GetExecutableDir; SYS_GetFi1eContents; SYS_GetFreeDiskSpace; SYS_GetFreeMemory; SYS_GetFreeResources; SYS_GetMemoryInfo; SYS_GetName; SYS_GetRegistryValue; SYS_GetVersion; SYS_Kin; SYS_MakeDir; SYS__MoveFile; SYS_RemoveDir; SYS_^RemoveFi 1 e; SYS_Restart; $YS_SetDir; SYS_SetDrive; SYSSetEnv; SYSSetRegistryValue; SYSVerifyText. Ha этот раз не станем рассказывать обо всех функциях — поговорим только о тех, которые используются наиболее часто. ПРИМЕЧАНИЕ
Поскольку SiikTest имеет объектно-ориентированную архитек туру, каждое из основных (первых) окон тестируемых или ис пользуемых в процессе тестирования программ должно быть определено в файле .inc как окно класса MainWin. Метод, опи санный далее, является методом именно этого класса.
функции работы с системой
119
MainWin.Start (sCmdLine. sDir. sExtensionReady. nInvokeTimeout) где sCMDLine — полный путь и имя программы; sDir — путь по умолча нию для запускаемой программы; sExtensionReady — функциональный определитель ожидания загрузкр! регистра программы; nInvokeTimeout — время задержки в секундах. Пример. Следующая строка кода открывает Notepad: Notepad.Start ("notepad.exe") SYSExecute (sCmdLine [, IsOutput])
где sCmdLine — командная строка DOS; sDir — переменная, хранящая stdout-вывод (необязательный параметр). Пример. Открытие autoexec.bat при помощи Notepad: SYS_Execute ("notepad c:\autoexec.bat")
Rational Robot Rational имеет две функции работы с системой: SQAShellExecute и StartApplication. Сами по себе эти функции практически идентичны, разнрищ только в том, что StartApplication ожидает от пользователя или исполняемый файл, или правильную строку запуска DOS, тогда как SQAShell Execute позволяет открыть файл, используя программу запуска, указанную в реестре. К примеру, файл с разрешением .DOC открывается с использованрхем Microsoft Word. Рассмотрим эти функции более детально. SQAShellExecute filenames, directory!, parameters! где filename! — полный путь и имя программы/файла; directory! — путь по умолчанию для запускаемой программы; parameters! — пара метры командной строки. Пример. Следующая строка кода открывает Notepad из StartMenu в Windows 95: SQAShell Execute "C:\WIN95\Start Menu\Programs\Accessories\ Notepad.lnk",""."" StartApplication Pathname!
где Pathname! — полный путь и имя запускаемой программы/файла. Может включать в себя параметры и правильно составленную стро ку запуска DOS. Пример. Следующая строка кода открывает autoexec.bat при по мощи Notepad: StartApplication "notepad c:\autoexec.bat"
120
Глава 5. Вспомогательные функции
Функции оповещения о результатах Когда выполнение скрипта закончено, вы (или ваш шеф), разумеет ся, хотели бы видеть результаты проделанной работы, иначе зачем вообще было ввязываться в это дело? То есть необходимо создать отчет о результате проведения автоматизированного теста. Причем желательно, чтобы его форма была интуитивно понятной, и одного взгляда на него было достаточно для понимания того, прошел тест или нет. А если вы находитесь только на стадии разработки скриптов, то и сообщения отладки не помешают... Каждый из производителей программных продуктов для автоматизации процессов тестирования имеет свое видение решения этой задачи, разработав функции опо вещения о результатах.
WinRunner Mercury Interactive предоставляет пользователю две функции опо вещения о результатах: tlstepO и reportmsgO. Разница заключается в следующем. Функция t I s t e p O используется только при необхо димости сообщить о результате проведенного теста. Она записывает статус (fail/pass) в файл результатов, маркируя его соответствующим цветовым кодом (fail — красный, pass — зеленый). Что же касается функции reportjnsgO, то она выводит сообщения в файл резуль татов. По сути, она используется только при отладке скриптов и не должна встречаться в «готовой» версии автоматизации. Рассмотрим эти функции более детально. tl_step (step_name, status, description)
где stepname — имя выполняемого шага; status — статус выполнения скрипта (О — pass; все остальное — fail); description — описание ошиб ки или выполняемого шага. Пример. Строка кода сообщает об удачном прохождении скрипта: tl_step ("Последний шаг". О, "Тест пройден без ошибок"); Пример. Сообщение о нахождении ошибки при прохождении скрипта: t1_step ("Проверка данных". -1, "Найдено несоответствие данных"): report msg (user msg)
где usermsg — строка, содержащая сообщение пользователя. Пример. Следующая строка кода сообщает инженеру текущее зна чение переменной j : reportmsg ("Значение переменной j : "&j);
функции оповещения о результатах
121
SilkTest в отличие от Mercury Interactive, Segue решила пойти другим путем. Создатели SilkTest справедливо рассудили, что помещать в файл ре зультатов нужно только сообщения об ошибках и предупреждения (нет ошибок — тест прошел успешно), и решили предоставить три функции оповещения о результатах: LogErrorO, LogWarning и PrintO. Первые две функции служат для сообщения об ошибке или внештат ной ситуации соответственно. Что же касается функции PrintO, то она несет ту же нагрузку, что и функция report_msg() в WinRunner, — выводит сообщение отладки. Рассмотрим эти функции более де тально. LogError (error_msg)
где error_msg — строка, описывающая произошедшую ошибку. Пример. Следующая строка кода сообщает о найденной при прохождерпп! скрипта ошибке: LogError ("Найдено несоответствие данных") LogWaring (warning_msg)
где warningmsg — строка, описывающая произошедшую внештатную ситуацию. Пример. Строка кода, сообщающая о том, что при прохождении скрипта не найден объект Name класса EditBox (при этом нет не обходимости останавливать скрипт, так как наличие этого класса желательно, но не обязательно): LogWarning ("Объект класса EditBox не найден") Print (user_msg)
где user_msg — строка, содержащая сообщение пользователя. Пример. Строка кода сообщает инженеру текущее значение пе ременной 7: Print ("Значение переменной j : "+Str(j));
Rational Robot Rational подошла к проблеме оповещения о прохождении скрипта, базируясь на старой присказке: «Одним махом семерых побивахом». Посему Rational Robot предоставляет пользователю всего одну функ цию оповещения результатов SQALogMessage. Эта функция в зависи мости от передаваемых параметров решает большинство проблем, возникающих при оповещении.
122
Глава 5. Вспомогательные функции
SQALogMessage code^, message$, descriptions где code^ — статус выполнения скрипта: • sqaPass — скрипт прошел без ошибок; • sqaFail — при прохождении скрипта найдена ошибка; • sqaWarning — при прохождении скрипта найдена внештатная си туация; • sqaNone — сообщение пользователя; messages — описание ошибки, сообщения или выполняемого шага; descriptions — детальное описание ошибки, сообщения или выпол няемого шага. Пример. Следующая строка кода сообщает об удачном прохож дении скрипта: SQALogMessage sqaPass, "Последний шаг", "Тест пройден без ошибок"
Пример. Сообщение о нахождении ошибки при прохождении скрипта: SQALogMessage sqaFai!, "Найдено несоответствие данных", ""
Пример. Строка кода, сообщающая о том, что при прохождении скрипта не найден объект Name класса EditBox (nppi этом нет необ ходимости останавливать скрипт, так как наличие этого класса желательно, но не обязательно): SQALogMessage sqaWarning, "Объект класса EditBox не найден", ""
Пример. Следующая строка кода сообщает инженеру текущее зна чение переменной/ SQALogMessage sqaNone, "Значение переменной j : " & Str(j), ""
Функции синхронизации Иногда при разработке автоматизации процессов тестирования нужно задержать исполнение скрипта на некоторое время. Примером может послужить ситуация, когда после входа в систему программный продукт тратит определенное время на авторизацию пользователя, не загружая следующее окно системы. Другим примером может по служить ожидание загрузки веб-страницы при медленном соедине нии с Интернетом. Каждый из производителей программных продуктов для автомати зации процессов тестирования имеет свое видение подобных про граммных решений и создает различные функции синхронизации.
функции синхронизации
123
WinRunner Mercury Interactive предоставляет две функции синхронизации: waitO и web_sync(). Разница между ними в том, что первая применяется в основном для искусственной задержки исполнения скрипта для лю бого программного продукта, тогда как вторая используется сугубо в интернет-программах и позволяет сделать скрипт независимым от скорости выхода в Интернет. Рассмотрим эти функции более де тально. wait (seconds, milliseconds)
где seconds — время задержки в секундах; milliseconds — время за держки в миллисекундах, задается только при первом параметре, рав ном нулю. Пример. Следующая строка кода задерживает выполнение скрипта на 10 с: wait (10): web^sync (seconds)
где seconds — время максимального ожидания загрузки веб-страницы. Пример. Строка кода задает ожидание загрузки веб-страницы в течение 10 с : web_sync (10):
Если страница загрузилась раньше, будет выполнена следующая строка кода.
Silkiest Segue имеет всего одну функцию синхронизации sleepO. Нельзя не отметить наличие хорошего чувства юмора у создателей SilkTest. Эта функция задерживает исполнение скрипта на заданное количество се кунд (хотя название функции говорит о том, что она скорее отправ ляет скрипт «баиньки» на это самое заданное количество секунд). sleep (seconds)
где seconds — время задержки в секундах. Пример. Следующая строка кода задерживает выполнение скрип та на 10 с: Sleep (10)
124
Глава 5. Вспомогательные функции
Rational Robot Rational решила поддержать Segue и также предоставить пользо вателю всего одну функцию синхронизации DelayFor. Назначение у нее то же самое, что и у wait в WinRunner и sleep в SilkTest — за держка исполнения скрипта на данное количество времени. DelayFor niilliseconcls$
где milliseconds$ — время задержки в миллисекундах. Пример. Задержка выполнения скрипта на 10 с: DelayFor 10000
Функции проверки существования объекта При разработке автоматизации процессов тестирования иногда нуж но проверить, существует необходимый нам объект или нет. При мером может послужить любая ситуация, когда один или несколько элементов интерфейса зависят от действий пользователя или от внутренней логики программного продукта. Для решения этой про блемы и используются функции проверки существования объекта. В большинстве своем они используются в паре с функциями син хронизации.
WinRunner Mercury Interactive предоставляет пользователю две функции про верки существования объекта: win_exists() и objexistsO. Разница между ними только в том, что первая используется в проверке суще ствования окна, тогда как вторая — для проверки существования объекта. win^exists (window)
где window — логическое имя или физическое описание окна. Пример. Следующая строка кода возвращает результат проверки суихествования окна PizzaOrder: result = win_exists ("PizzaOrder"); obj^exists (object)
где object — логическое имя или физическое описание объекта.
функции проверки существования объекта
125
Пример. Строка кода возвращает результат проверки существо вания объекта CreditCard: result = obj^exists ("CreditCard");
SilkTest в отличие от Mercury Interactive, Segue, используя потенциал объ ектно-ориентированной архитектуры, предоставила пользователю все го одну функцию, а вернее сказать метод проверки существования объекта ExistsO. Поскольку этот метод определен в классе AnyWin, который является родительским по отношению ко всем объектам пользовательского интерфейса, определенных в SilkTest, данный ме тод может быть использован как для окна, так и для любого иного объекта. Рассмотрим этот метод более детально на практических примерах. object.Exists О
где object — логическое имя объекта/окна. Пример. Следующая строка кода возвращает результат проверки существования окна PizzaOrder: result = PizzaOrder.ExistsO
Пример. Строка кода возвращает результат проверки существо ваний объекта CreditCard: result = CreditCard. ExistsO
Rational Robot Rational так же, как и Segue, предоставил пользователю всего одну функцию синхронизации — SQAFindObjectO. Эта функция возвраща ет результат поиска данного объекта. SQAFi ndObject(гесТуре$)
где гесТуре$ — способ определения объекта. Пример. Следующая строка кода возвращает результат проверки существования объекта CreditCard: result = SQAFi ndOb ject ("Type=ComboBox;name=CreditCard")
Хотелось бы также отметить наличие функции SQAWaitForObject, яв ляющейся как бы симбиозом функции синхронизации и функции определения существования объекта.
126
Глава 5. Вспомогательные функции
SQAWai tForOb ject (гесТуре$. mi 11 i seconcls&)
где гесТуре$ — способ определения объекта; miniseconds& — время за держки в миллисекундах. Пример. Следующая строка кода ждет появления объекта CreditCard в течение 10 с: result »SQAWaitForObject("Type-ComboBox;name=CreditCardMOOOO)
Функции работы с файлами Время от времени в процессе создания автоматизированного тести рования возникает необходимость получить информацию из файла (Word, Excel и т. д.) или записать нужную информацию в файл оп ределенного формата. Именно для обслуживания подобных ситуаций и существует группа функций работы с файлами.
WinRunner Mercury Interactive предоставляет пять функций работы с файлами: file_open(), file^compareO, file^getline, file__printf() и file__close(). Рассмотрим эти функции более детально на практических примерах. file__open (file^name, mode)
Функция, открывающая файл для работы с ним (запись и/или чте ние), где file_name — полное имя открываемого файла; mode — свой ство открываемого файла, может быть следующим: • FO_MODE_READ, или О — только чтение; • FO^MODE^WRITE, или 1 — только запись; • FO__MODE_APPEND, или 2 — только запись в конец файла. Пример. Следующая строка кода открывает файл C:\readme.txt: f i 1 e_open( "С: Wreadme. txt", FO__MODE^READ): file^compare ( f i l e l . file2 [. save^file])
Данная функция сравнивает содержимое двух файлов, где filel -полное имя сравниваемого файла; file2 — полное имя файла, с кото рым сравнивают filel; save_file — полное имя файла, в который бу дут сохранены файлы после сравнения (необязательный параметр). Пример. Следующая строка кода сравнивает файлы win.ihi и winl.ini: file__compare("c:\\win31\\win.ini"."c:\\win31\\winl.ini"."save");
функции работы с файлами
127
file_getline ( filename, o u t l i n e )
Функция, считывающая одну строку из указанного файла, где file_name — полное имя открываемого файла; outline — переменная, хранящая прочитанную строку. Пример. Строка кода считывает одну строку из файла C:\readme.txt: file_getline("С:\\readme.txt".1ine): f i l e p r i n t f (filename, format, expl [ , exp2
ехрЗО ])
Данная функция записывает форматированное значение в файл, где f i 1 ename — полное имя открываемого файла; format — спецификатор формата; expl, ехр2,... ехрЗО — форматируемые выражения для за писи в файл. Пример. Запись одной строки в файл C:\readme.txt: file_printf ("C:\\readme.txt","^s ", "Одна строка"): file_close (filename)
Функция, закрывающая файл по окончании работы с ним (запись и/или чтение), где filename — полное имя открываемого файла. Пример. Следующая строка кода закрывает файл C:\readme.txt: file_close("С:\\readme.txt");
SilkTest Segue имеет семь функций работы с файлами: FileCloseO, FileOpenO, FileReadLineO, FileReadValueO, FileSetPointerO, FileWriteLineO и FileWriteValueO. Давайте более детально рассмотрим эти функции на практических примерах. hFile = FileOpen (sPath, fmMode [, fsShare])
Данная функция открывает файл для работы с ним (запись и/или чтение), где hFile — идентификатор (handle) файла типа HFILE; sPath — полное имя открываемого файла; fmMode — свойство открываемого файла, может быть следующим: • FMREAD — только чтение; • FMWRITE — только запись. Если файл уже существует, его содер жимое удаляется, а сам файл сжимается до О байт; • FMUPDATE — то же, что и FMWRITE, только размер файла сохраняет ся (но содержимое удаляется); • FMAPPEND — только запись в конец файла.
1 28
Глава 5. Вспомогательные функции
Пример. Следующая строка кода открывает файл C:\readme.txt: OutputFileHandle = FneOpen ("readme.txt ". FMWRITE) FileSetPointer (hFile. iNewValue [. SetMode])
Данная функция устанавливает позицию чтения/записР! в файле, где hFile — идентификатор (handle) файла типа HFILE; iNewValue — новое значение позиции; setMode — свойство позиции (необязательный па раметр), может быть следующим: • FP^START — позиция равна iNewValue (значение по умолчанию); • FPEND — позиция равна iNewValue + длина файла; • FPRELATIVE — позиция равна iNewValue + нынешняя позиция. Пример. Строка кода, устанавливающая позицию чтения/записи на четвертый символ с конца: FileSetPointer (OutputFileHandle, -4. FPEND) FileReadLine (hFile, sLine)
Функция, считывающая одну строку из указанного файла, где hFile — идентификатор (handle) файла трша HFILE; sLine — переменная, хра нящая прочитанную строку. Пример. Считывание одной строки из файла C:\readme.txt: FileReadLine (OutputFileHandle, sLine) FileReadValue (hFile. aValue)
Эта функция считывает одну форматированную строку из указанно го файла, где hFile — идентификатор файла типа HFILE; aValue — дан ные определенного формата для записи в файл. Пример. Считывание одной строки из файла C:\readme.txt (см. опи сание функции FileWriteValue): FileReadValue (OutputFileHandle, Item) FileWriteLine (hFile, sLine),
Данная функция записывает одну строку в файл, где hFile — иден тификатор файла типа HFILE; sLine — переменная, хранящая выраже ния для записи в файл. Пример. Строка кода записывает одну строку в файл C:\readme.txt: FileWriteLine (OutputFileHandle, " Одна строка ") FileWriteValue (hFile. aValue)
Функция, записывающая форматированное значение в файл, где hFile — идентификатор файла типа HFILE; aValue — данные опреде ленного формата, подготовленные для записи в файл.
функции работы с файлами
1 29
Пример. Запись одной строки в файл C:\readme.txt: FileWriteValue (OutputFileHandle. "{'Bob'. 46}") FileClose (hFile)
Функция, закрывающая файл по окончании работы с ним (запись и/или чтение), где hFile — идентификатор файла типа HFILE. Пример. Следующая строка кода закрывает файл C:\readme.txt, от крытый функцией FileOpen: FileClose (OutputFileHandle)
Rational Robot Rational предоставила пользователю 21 функцию работы с файлами: Close, Eof, FreeFile, Get, Input Function, Input Statement, Line Input, Loc, Lock, Lof, Open, Print, Put, Reset, Seek Function, Seek Statement, Spc, Tab, Unlock, Width PI Write. He станем рассказывать про все функции. Рас смотрим на практических примерах функц1П1, используемые наибо лее часто. Open filenames [For mode] [Access access] As filenumber^
Данная функция открывает файл для работы с ним (запись и/или чтение), где filename — полное имя открываемого файла; mode — свойство открытого фархла, может быть следующим: • Input — последовательное чтение из файла; • Output — последовательная запись в файл; • Append — последовательное добавление в файл; • Random — случайный доступ; • Binary — доступ к бинарным данным. access — настройка характера работы с файлом, может быть следу ющей: • Read — только чтение; • Write — только запись; • Read Write — запись и чтение (значение по умолчанию); filenumber^ — цифра от 1 до 255, назначаемая файлу. Пример. Открытие файла C:\readme.txt: Open "C:\readme.txt " For Input As #1
130
Глава 5. Вспомогательные функции
Seek filenumber^, positions
Функция, устанавливающая позицию чтения/запрюи в файле, где filenumber^ — цифра от 1 до 255, назначаемая файлу; positions — но вое значение позиции. Пример. Установка позиции чтения/записи на четвертый символ с начала: Seek#l. 4 Line Input filenumber^, varnameS
Данная функция считывает одну строку из указанного файла, где filenumber^ — цифра от 1 до 255, назначаемая файлу; varname$ — пе ременная, хранящая прочитанную строку. Пример. Следующая строка кода считывает одну строку из фай ла C:\readme.txt: Line Input #1, OneString Print filenumber^. expression!ist
Функция записи одной строки в файл, где filenumber^ — цифра от 1 до 255, назначаемая файлу; expression!ist — переменная, хранящая выражения для записи в файл. Пример. Запись одной строки в файл C:\readme.txt: Print #1. " Одна строка " C!ose fi!enumber^
Функция, закрывающая файл по окончании работы с ним (запись и/или чтение), где fi!enumber^ — цифра от 1 до 255, назначенная файлу в функции Open. Пример. Следующая строка кода закрывает файл C:\readme.txt, открытый функцией Open: C!ose#l
Практический пример 1 Рассматриваемая ситуация: тестирование приложения Pizza Order. Задача тестирования: проверить, что объект Name класса EditBox су ществует, ввести в него значение 1!уа Vinnichenko, вывести сообще ние о результатах теста и записать их в файл.
Практический пример 1
131
Тест-скрипт: 1. Активизировать окно. 2. Проверить наличие объекта Name класса EditBox. О Если объекта нет, то подождать 10 секунд. О Если объект не появился, вывести сообщение об ошибке и пе рейти к шагу 5, в противном случае перейти к шагу 3. 3. Щелкнуть мышью на объекте Name класса EditBox. 4. Ввести имя Пуа Vinnichenko. 5. Вывести сообщение о результатах тестирования и сохранить их в файл.
WinRunner # Активизировать окно: set_window ("Pizza Ordering Page"): # Проверить наличие объекта Name класса EditBox. # Если объекта нет, то подождать 10 с: if (obj__exists("name",10) != Е_ОК) { # Если объект не появился, вывести сообщение об ошибке и перейти к шагу 5, в противном случае перейти к шагу 3: tl_step("Проверка объекта".-!."Объект Name класса EditBox не найден"): tresult = "Объект не найден": } else # Щелкнуть мышью на объекте Name класса EditBox: obj_mouse_click ("name". 217, 34. LEFT): # Ввести имя Ilya Vinnichenko: obj_type ("name"."Пуа Vinnichenko"): tresult = "Тест пройден успешно": } # Вывести сообщение о результатах тестирования и сохранить их в файл: report_msg(tresult): file__open ("C:\\resuns.txt". FOJODE__APPEND): file^printf ("C:\\ results.txt \"Xs ". tresult): file^close ("C:\\results.txt"):
SilkTest // Обозначить данные: HFILE OutputFileHandle STRING tresult // Активизировать окно:
132
Глава 5. Вспомогательные функции
Pi zzaOrder.SetActi ve() // Проверить наличие объекта Name класса EditBox. // Если объекта нет. то подождать 10 с: if (Name.Exists()=-FALSE) // Если объект не появился, вывести сообщение об ошибке и перейти к шагу 5, в противном случае перейти к шагу 3: LogError ("Объект Name класса EditBox не найден ") tresult = "Объект не найден" else // Щелкнуть мышью на объекте Name класса EditBox: Name.Click О ; // Ввести имя П у а Vinnichenko: Name.TypeKeys ("Ilya Vinnichenko") tresult = "Тест пройден успешно" // Вывести сообщение о результатах тестирования и сохранить их в файл: print(tresult) OutputFileHandle = FileOpen ("C:\results.txt ". FM_APPEND) FileWriteLine (OutputFileHandle, tresult) FileClose (OutputFileHandle)
Rational Robot ' Обозначить данные: Dim tresult As String Dim Result As Integer 'Активизировать окно: Window SetContext, "Caption=PizzaOrder" ' Проверить наличие объекта Name класса EditBox. ' Если объекта нет, то подождать 10 с: Result = SQAWaitForObject("Type=EditBox:name=name",10000) If Result = sqaSuccess Then ' Щелкнуть мышью на объекте Name класса EditBox: EditBox Click, "Name=name", "Coords=91,12" ' Ввести имя Ilya Vinnichenko: InputChars " Ilya Vinnichenko" tresult = "Тест пройден успешно" Else 'Если объект не появился, вывести сообщение об ошибке и перейти к шагу 5, в противном случае перейти к шагу 3: SQALogMessage sqaFail. " Объект не найден", "" tresult = "Объект не найден" End If * Вывести сообщение о результатах тестирования и сохранить их в файл: SQALogMessage sqaNone, tresult. "" Open "C:\result.txt " For Append As #1 Print #1, tresult Close #1
Глава 6 Функции работы с базами данных
в данной главе речь пойдет о функциях работы с базами данных. Не секрет, что большинство серьезных программных продуктов, имею щихся на рынке, так или иначе связаны с базами данных. Каждый раз, когда мы имеем дело с большим массивом данных, с почти сто процентной уверенностью можно предположить, что «на другом кон це» находится реляционная база данных. Стандартная архитектура большинства современных бизнес-приложений представляет собой комбинацию Application/Web Server и Database Server. В подобной ситуации Application/Web Server принимает на себя всю функцио нальную нагрузку, а Database Server занимается хранением и обра боткой данных. Обмен информацией между серверами выполняется посредством протокола ODBC (Open Data Base Connectivity) или, если это Java Application, посредством протокола JDBC Qava Data Base Connectivity). В обоих случаях в качестве основного инструмен та извлечения и последующей обработки данных используется язык запросов SQL (Structured Query Language). В этой книге не будем приводить описание SQL. Это очень объем ная тема, которой посвящено множество книг. Здесь же определим требования к программному продукту автоматизации процесса тес тирования для работы с протоколами ODBC и JDBC. Сразу следует отметить, что программное обеспечение для работы с ODBC входит в стандартную поставку любого из описываемых программных про дуктов. При этом модули для работы непосредственно с JDBC, как в принципе и модули для работы с Java-приложениями являются от дельным программным продуктом и поставляются как Add-on (до полнительный модуль) к базовому приложению. Исходя из сказан ного основной упор в этой главе будет сделан на работу с ODBC.
134
Глава 6. Функции работы с базами данных
Какие же требования можно предъявить к программному продукту автоматизации процесса тестирования? По сути, требование одно: ПО должно поддерживать основные API-функции протокола ODBC: • ConnectO; • DisconnectO; • ExecuteO; • UpdateO; • FetchO; • CommitO; • RollbackO.
К сожалению, HPI один из опргсываемых программных продуктов не поддерживает все функции этого списка. А например к реализации функции FetchO у каждой из этих программ имеется собственный подход.
WinRunner Mercury Interactive предоставляет пользователю 11 функций работы с базами данных. db__connect (session_name, connection^string)
где sessionname — имя, присваиваемое данному сеансу связи; соппесtion_string — параметры связи с базой данных (БД) ODBC. Функция открывает сеанс связи с БД (функция ConnectO протокола ODBC). Пример. Следующая строка кода открывает сеанс связи с БД по ее DSN-имени и присваивает данному сеансу имя queryl для ис пользования в других функциях работы с БД: db__connect ("queryl", "DSN=F1 ight32"); db^disconnect (session^name)
где session^name — имя, присвоенное данному сеансу связи. Функция закрывает сеанс связи с БД (функция DisconnectO прото кола ODBC). Пример. Закрытие сеанса связи с базой данных, открытой в пре дыдущем примере: db_disconnect ("queryl");
WinRunner
135
clb_execute_query (session_name, SQL. record_number) где sessionname — имя, присвоенное данному сеансу связи; SQL — SQLзапрос; record_number — переменная, хранящая количество строк в воз вращаемой таблице. Функция выполняет SQL-запрос (функция ExecuteO протокола ODBC). Пример. Следующая строка кода выполняет запрос, получает возвращаемую таблицу и количество строк в этой таблице: db_execute_query ("queryl", "SELECT * FROM Orders",record__number):
db_get_row (session^name, row_index, row_content) где session_name — имя, присвоенное данному сеансу связи; row^index — порядковый помер строки (О — первая строка); row_content- пере менная, хранящая возвращаемую строку. Функция возвращает строку таблицы, полученную как результат SQL-запроса, выполненного функцией db_execute_query (частичная реализация функции FetchO протокола ODBC). Пример. Следующая строка кода возвращает шестую строку таб лицы, полученной в предыдущем примере (значения столбцов в строке разделены табуляцией): db_get_row("queryl",5.row_content):
db_get_fiel devalue (session_name, row^index, column) где session_name — имя, присвоенное данному сеансу связи; row^index — порядковый номер строки (О — первая строка); column- порядковый номер столбца (О ~ первый столбец). Функция возвращает указанную ячейку (значение поля) таблицы, полученную как результат SQL-запроса, выполненного функцией db_execute_query (частичная реализация функции FetchO протокола ODBC). Пример. Следующий блок кода возвращает значение ячейки вто рого столбца во второй строке таблицы, полученной в примере использования функции db_execute_query(): val -db^get_field_value ("queryl"."#Г'."#1"); db__get_row( "queryl", 5, row^content): db_get_headers (session^name. header_count. header_content)
где sessionname — имя, присвоенное данному сеансу связи; header^ count — количество столбцов; headercontent — значения столбцов.
136
Глава 6. Функции работы с базами данных
Функция возвращает количество и значения заголовков столбцов таб лицы, полученной как результат SQL-запроса, выполненного функ1Ц1ей db_execute_query: Пример. Следующая строка кода возвращает количество и значе ния заголовков столбцов таблицы, полученной в примере db_ execute^queryO: db_get_headers ("queryl",field_num,headers): db_get_last_error (session_name, error)
где sessionname — имя, присвоенное данному сеансу связи; error — сообщение об ошибке. Функция возвращает последнюю ошибку, возникшую при проведе нии данного сеанса связи. Пример. Возвращение последней ошибки, возникшей при прове дении сеанса связи queryl: db_get_1ast_error("queryl".error): ПРИМЕЧАНИЕ
Упомянутые ранее функции db_check(), db_record_check(), db_ vvTite_rccords() и db_dj_convert() отражают особый подход WinRunner к тестированию баз данных и в данной книге огшсываться не будут.
SilkTest Segue предлагает 17 функций работы с базахми данных. Следует от метить, что поскольку SilkTest имеет объектно-ориентированную архитектуру, его система отладки ошибок базируется на всей мощи ООП. Так, любая из перечисленных далее функций в случае обна ружения ошибки выдает нужное сообщение системы. hdbc = DB^Connect ("con_string")
где hdbc — идентификатор (handle) данного сеанса связи; constring — параметры связи с базой данных ODBC формата (DSN=""[:SRVR="": UID="":PWD=""]); DSN — DSN-имя базы данных; SRVR — имя сервера БД (необязательный параметр); UID — имя пользователя БД (необяза тельный параметр); PWD — пароль пользователя БД (необязательный параметр). Функция открывает сеанс связи с БД (функция Connect О протокола ODBC).
Silkiest
137
Пример. Следующая строка кода открывает сеанс связи с базой данных по ее DSN-имени и генерирует его идентификатор для использования в других функциях работы с БД: hdbc = DB_Connect ("DSN= Flight32") DB_Disconnect (hdbc)
где hdbc — идентификатор подключения данного сеанса связи. Функция закрывает сеанс связи с БД (функция Disconnect О прото кола ODBC). Пример. Закрытие сеанса связи с БД, открытой в предыдущем примере: DBDisconnect (hdbc) hstmnt = DB_Execute$ql (hdbc. "sql_stmnt")
где hstmnt — идентификатор возвращенной таблицы; hdbc — иден тификатор подключения (handle) данного сеанса связи; sqlstmnt — SQL-запрос. Функция выполняет SQL-запрос (функция ExecuteO протокола ODBC). Пример. Выполнение запроса и получение идентификатора воз вращенной таблицы: hstmnt = DBJxecuteSql (hdbc. " SELECT * FROM Orders ") status = DB_FetchNext (hstmnt, . . . )
где status — статус возвращаемой строки, FALSE — если строк больше нет; hstmnt — идентификатор возвращенной таблицы; ... — список переменных, каждой из которых будет передано значение одного столбца в возвращаемой строке. Функция возвращает следующую строку таблицы, полученную как результат SQL-запроса, выполненного функцией DB_ExecuteSql (час тичная реализация функции FetchO протокола ODBC). Пример. Возвращение следующей строки таблрщы, полученной в предыдущем примере: DBFetchNext (hstmnt. order_number. product) status = DB_FetchPrev (hstmnt. . . . )
где status — статус возвращаемой строки (FALSE, если строк больше нет); hstmnt ~ идентификатор возвращенной таблицы; ... — список переменных, каждой из которых будет передано значение одного столбца в возвращаемой строке.
138
Глава 6. Функции работы с базами данных
Функция возвращает предыдущую строку таблицы, полученную как результат SQL-запроса, выполненного функцией DBExecuteSql (час тичная реализация функции FetchO протокола ODBC). Пример. Данная строка кода возвращает следующую строку таб лицы, полученной в предыдущем примере: DB_FetchPrev (hstmnt, order_number, product) DBFinishSql (hstmnt)
где hstmnt — идентификатор возвращенной таблицы. Функция уничтожает таблицу, полученную как результат SQL-за проса, выполненного функцией DB_Execute$q1. Использование этой функции является обязательным завершением работы с запросом. Пример. Следующая строка кода закрывает сеанс связи с БД, от крытой в предыдущем примере: DB_FinishSql (hstmnt) ПРИМЕЧАНИЕ
Упомянутые ранее функции DB_ColumnPrivileges, DB_Columns, DB_ForeignKeys, DB_GetConnectAttr, DB_PrimaryKcys, DB_ ProcedureColumns, DB_Procedures, DB_SetConnectAttr, DB_ Special Columns, DB_Statistics, DB_TablePrivileges отражают осо бый подход SilkTest к тестированию баз даьшых и в данной книге рассматриваться не будут.
Rational Robot Rational предлагает пользователю 8 функций работы с базами дан ных. connection = SQLOpen (connectStr$)
где connection — значение, присваиваемое данному сеансу связи; connectStr$ — параметры связи с базой данных ODBC. Функция открывает сеанс связи с БД (функция Connect О протокола ODBC). Пример. Следующая строка кода открывает сеанс связи с БД по ее DSN-имени и присваивает данному сеансу значение, храня щееся в переменной connection для использования в других функциях работы с БД: connection = SQLOpen("DSN= Flight32")
Rational Robot
139
SQLClose (connection&)
где connection& — значение, присвоенное данному сеансу связи SQLOpen. Функция закрывает сеанс связи с БД (функция Disconnect О прото кола ODBC). Пример. Закрытие сеанса связи с БД, открытой в предыдущем примере: SQLClose(connection) SQLExecQuery (connections . query$)
где connections — значение, присвоенное данному сеансу связи SQLOpen; queryS — SQL-запрос. Функция выполняет SQL-запрос (функция ExecuteO протокола ODBC). Пример. Следующая строка кода выполняет запрос, получает воз вращаемую таблицу и количество строк в этой таблице: SQLExecQuery(connection, "SELECT * FROM Orders") SQLRetri eve (connections. destinationO, maxColumns^. maxRows^. columnNames^. rowNumbers^. fetchFirst^)
где connections — значение, присвоенное данному сеансу связи SQLOpen; destinationO — двумерный массив, хранящий возвращаемые значения; maxColumns^ — количество возвращаемых столбцов (необя зательный параметр); maxRows^ — количество возвращаемых строк (необязательный параметр); columnNames^ — флаг возврата имен столб цов (1 — возвращать как первую строку массива, О — не возвращать имена столбцов) (необязательный параметр); rowNumbers^ ~ флаг возврата номеров строк (1 — возвращать, О — не возвращать номера строк) (необязательный параметр); fetchFirst^ — флаг первой стро ки (ряда) (1 — первая строка) (необязательный параметр). Функция возвращает строку таблицы, полученную как результат SQL-запроса, выполненного функцией SQLExecQuery (частичная реа лизация функции FetchO протокола ODBC). Пример. Возвращение первой строки таблицы, полученной в пре дыдущем примере: SQLRetrieve(connection:"Connection. destination:-destination. maxRows:-!) SQLError (destinationO)
где destinationO — двумерный массив, хранящий сообщение об ошибке.
140
Глава 6. Функции работы с базами данных
Функция возвращает последнюю ошибку, возникшую во время дан ного сеанса связи. Пример. Строка кода, возвращающая последнюю ошибку, воз никшую во время сеанса связи: SQLError destination:=errors
Практический пример 2 Рассматриваемая ситуация: тестирование приложения с трехуров невой архитектурой!. Назовем его интернет-магазином. Приложение имеет веб-интерфейс пользователя, Webserver/Application Server, обрабатывающий логику приложения, и DataBase Server. Для про стоты БД представлерш в виде таблицы следующей структуры. ORDERS
order_number procluct_name unit^price customer
Задача тестирования: проверить, что в БД содержатся следующие данные: order_number
product_name
unit^price
customer
001
Monitor
500
VIV Corp
001
CPU
400
VIV Corp
001
Keyboard
50
VIV Corp
001
Mouse
20
VIV Corp
Тест-скрипт: 1. Обозначить ожидаемые данные. 2. Открыть сеанс связи с БД. 3. Выполнить SQL-запрос. 4. Произвести выборку и проверку данных. 5. Закрыть сеанс связи с БД.
Практический пример 2
141
WinRunner # Обозначить ожидаемые данные: public ExpectedData [] = { "001|Monitor|500|VIV|Corp.". "001|CPU|400|VIV Corp.". "0011 Keyboard 1501VIV Corp.". "0011 Mouse 1201VIV Corp." }: # Открыть сеанс связи с БД: db_connect ("queryl","DSN= TestApp"): # Выполнить SQL-запрос: db_execute_query ("queryl","SELECT * FROM Orders".record_number); # Произвести выборку и проверку данных: for (i=0; i<4; i++) { db_get_row("queryl".i,row_content); sp1it(row_content. tmpRet, "\t"): split(ExpectedData [i]. tmpExp, " | " ) ; if (tmpRet!= tmpExp) tl_step("Проверка данных",-1."Найдено несовпадение данных") report_msg("Ожидаемые значения: " & tmpExp) report_msg ("Возвращаемые значения: " & tmpRet) } # Закрыть сеанс связи с БД: db_disconnect ("queryl");
SilkTest // Обозначить ожидаемые данные: INTEGER i=l STRING tmp, order^number, product__name, unit^price, customer LIST OF STRING ExpectedData = {..} "0011 Monitor 15001VIVI Corp." "0011 CPU 14001VIV Corp." "0011 Keyboard 1501VIV Corp." "0011 Mouse 1201VIV Corp." // Открыть сеанс связи с БД: hdbc = DB_^Connect ("DSN= TestApp") // Выполнить SQL-запрос: hstmnt = DBJxecuteSql (hdbc. " SELECT * FROM Orders ") // Произвести выборку и проверку данных: while (DB_FetchNext (hstmnt, order_number, product_name, unit_price, customer)) tmp = order_number +"\"+ product_name -••"1"+ unitprice +"|"-»customer if (tmp != ExpectedData[i]) LogError("Найдено несовпадение данных") LogError("Ожидаемые значения: "+ExpectedData[i])
142
Глава 6. Функции работы с базами данных LogError ("Возвращаемые значения: " + tmp)
DBJinishSQL (hstmnt) / / Закрыть сеанс связи с БД: DB__Disconnect (hdbc)
Rational Robot ' Обозначить ожидаемые данные: Dim connection As Long Dim destinationd To 4, 1 To 4) As Variant Dim ExpectedData As String Dim ActualData As String ExpectedData - "|001|Monitor|500|VIV|Corp.|001|CPU|400|VIV Corp.|" & "0011 Keyboard 1501VIV Corp.10011Mouse]201VIV Corp." ActualData - "" * Открыть сеанс связи с БД: connection - SQLOpen("DSN» TestApp") * Выполнить SQL-запрос: SQLExecQuery(connection. "SELECT * FROM Orders") ' Произвести выборку и проверку данных: SQLRetrieve(connection:*connection,destination:=destination, columnNames:«О.rowNumbers:-О,maxRows:-4, maxColumns:"4.fetchFi rst:«0) For X - 0 to 4 For у - 0 to 4 ActualData » ActualData & "|" & destination(x,y) Next у Next X If ActualData <> ExpectedData then SQALogMessage sqaFail, "Найдено несоответствие данных". "" End If ' Закрыть сеанс связи с БД: SQLClose(connection)
Глава 7 Обработка ошибок
в этой главе поговорим о такой несомненно важной теме, как обра ботка ошибок исполнения. Автоматизация процессов тестирования — это тоже программирование. И здесь, как и в «обычном» програм мировании, может возникнуть ситуация, не предусмотренная вашим скриптом. Именно для решения подобных проблем и существуют обработчики ошибок выполнения. Пожалуй, наиболее распростра ненной ошибкой автоматизации процессов тестирования является отсутствие нужного объекта на странице или же наличие этого объ екта, но со свойствами, отличными от ожидаемых. Этот список мо гут дополнить также ошибки работы с протоколом ODBC, ошибки приведения типов данных и т. д. В общем, обработчики ошибок — вещь нужная и полезная. Стандартный обработчик событий представляет собой языковую конструкцию следующего типа: НАЧАЛО ОБРАБОТЧИКА ВЫПОЛНЯЕМЫЙ КОД ОБРАБОТКА ОШИБКИ ВЫПОЛНЯЕМЫЙ КОД
Действует обработчик по следующему сценарию: 1. Выполнить исполняемый код внутри тела конструкции. 2. Проверить наличие ошибок исполнения: О если ошибки найдены, произвести обработку и выполнить со ответствующий код; О если ошибок нет, пропустить исполняемый код обработчика и продолжить выполнение кода.
144
Глава 7. Обработка ошибок
Следует сразу отметить, что максимальная отдача от подобного об работчика будет получена при использовании объектно-ориентиро ванной архитектуры. То есть SilkTest оставляет далеко позади всех своих конкурентов. Также хотелось бы отметить, что в этой книге не будут опР1Сываться обработчики событий, «вмонтированные» в эле менты графического интерфейса пользователя описанного ПО. Пе рейдем непосредственно к описанию обработчиков ошибок.
WinRunner Mercury Interactive предлагает собственную систему обработки оши бок, отличающуюся от описанной в начале данной главы. WinRunner позволяет выбрать или создать свой «жестко кодированный» вариант обработчика, используя элементы графического интерфейса WinRunner. Для работы с этими обработчиками используется набор функций: define_object_exception, definepopupexception, definetsl, exceptionoff, exception_off, except ionon.
SilkTest Segue имеет, пожалуй, наиболее удачную и настраиваемую систему обработки ошибок. Обладая объектно-ориентировашюй архитектурой, SilkTest рассматривает ошибку как объект, что позволяет напрямую обрабатывать ошибку на любом уровне вложенности. Система обработки ошибок SilkTest базируется на двух китах: кон струкции do...except и функциях работы с данными ошибки как с объ ектами. Рассмотрим их более детально. Конструкция do...except — типичный обработчик ошибок языков выс шего уровня. В первой части конструкции происходит выполнение кода-под-наблюдением, а во второй — непосредственно обработка произошедшей ошибки: do
statementsl except statements2
где statementsl — блок кода-под-наблюдением; statements2 ~ блок кода, непосредственно обрабатывающий произошедшую ошибку.
SJikTest
145
Пример. Следующий блок кода открывает сеанс связи с базой данных по ее DSN-имени и генерирует его идентификатор под ключения (handle) для использования в других функциях работы с БД. В случае ошибки выдается ошибка исполнения: do hdbc = DB_Connect ("DSN= FT ight32") except LogError ("Невозможно открыть сеанс связи с БД")
Иногда возникает необходимость — если, конечно, у вас развитая сеть обработки ошибок ~ самому «вызвать» ошибку Р1з скрипта. Зачем это может понадобиться? Например, в случае, если возьпгкшая ситуа ция не является ошибочной для SilkTest, но становится серьезной ошибкой для вас. Примером может послужить неправильное значе ние баланса в бухгалтерской программе. При такор! ошибке все по следующие тест-скрипты не будут иметь смысла, но для SilkTest это не является ошибкой. В этих случаях применяются функции raise PI reraise. Функция raise используется для «ручрюго» (а не по умолчанию) вызова ошибки из кода и имеет следующий синтаксис: raise [integer-expr [. expr [, cmd-line]]]
где integer-expr — код ошибки (необязательный параметр); ехрг — опи сание ошибки (необязательный параметр); cmd-line — строка, запи сываемая в файл результатов вместе с сообщением об ошибке. Функция reraise используется в тех случаях, когда обработчик не ожидает ошргбки и Baivi нужно передать сообщение «выше по лестни це» для обработчиков на уровне скрипта или даже тест-сценария. Функция имеет следующей! синтаксис: reraise
Пример. Следующий блок кода открывает сеанс связи с базой данных по ее DSN-имени и генерирует его идентификатор под ключения для использования в других функциях работы с БД: do
hdbc = DB__Connect ("DSN= Flight32") do hstmnt = DB_ExecuteSq1 (hdbc. " SELECT * FROM Orders ") DB_FetchNext (hstmnt, order_number, product) if (order^number !="10") raise 1, "ERROR: Test verification failed"
146
Глава 7. Обработка ошибок
except LogError ("Проблема с запросом к БД") reraise except LogError ("Невозможно открыть сеанс связи с БД")
Сначала выдается ошибка исполнения. Затем происходит выпол нение запроса к БД, а в случае несоответствия вызывается ошибка. Ошибки на уровне DBExecuteSql также передаются обработчику на уровне DB_Connect. Функции работы с ошибками можно разделить на две категории: 1. Служебные: О ExceptClearO — очищает информацию о текущей ошибке; О ExceptPrintO — вводит данные об ошибке в фар1л результатов; О ExceptLogO — вводит сообщение об ошибке в файл резуль татов. 2. Функции получения данных: О ExceptCallsO — возвращает «функциональный след» ошибки; О ExceptDataO — возвращает информацию об ошибке; О ExceptNumO — возвращает цифровой код ошибки.
Rational Robot Rational имеет те же возможности обработки ошибок, что и VBScript. Это не много, но и не так уж мало. Средства обработки ошибок Ra tional Robot представляют собой конструкции On Error...Go to и On Error...Resume Next и функции Err и Error. Конструкция On Error...Go to -- типичный обработчик ошибок VBScript. В случае обнаружения ошибки в обрабатываемом коде исполнение передается блоку кода, указанному в Go to-части конструкции: On Error Go to ErrHdU statementsl ErrHdll: statements2
где statementsl — блок кода-под-наблюдением; state!nents2 — блок кода, непосредственно обрабатывающий произошедшую ошибку.
Rational Robot
147
Пример. Следующий блок кода открывает сеанс связи с базой данных по ее DSN-имени и генерирует его идентификатор под ключения для использования в других функциях работы с БД: On Error Go to ЕггНсП 1 connection = SQLOpen("DSN= Flight32") ErrHdll: SQALogMessage sqaFail, " Невозможно открыть сеанс связи с БД ", ""
В случае ошибки выдается ошибка исполнения. Конструкция «On Еггог..Яе$ите Next» — также обработчик ошибок VBScript. В случае обнаружения ошибки в обрабатываемом коде исполнение передается строке кода, следующей после той, в которой произошла ошибка: On Error Resume Next statementl statement2
где statementl — строка кода-под-наблюдением; statement2 — строка, непосредственно обрабатывающая произошедшую ошибку. Пример. Следующий блок кода открывает сеанс связи с базой дан ных по ее DSN-имени и генерирует его идентификатор подключения для использования в других функциях работы с БД: On Error Resume Next connection = SQLOpen("DSN= Flight32") I f Err!=0 SQALogMessage sqaFail, " Невозможно открыть сеанс связи с БД ", "" End I f
Rational Robot предлагает следующие функции работы с ошибками: • ЕгТ — возвращает номер строки, в которой произошла ошибка; • Error О — возвращает информацию об ошибке; • Err = п^ — возвращает цифровой код ошибки, где п^ — переменная, получающая код; • ЕггО — возвращает цифровой код последней «пойманной» ошибки; •
Error errornumber^ — осуществляет «ручной» вызов ошибки с ко дом errornumber^.
Глава 8 Функции пользователя
в этой главе речь пойдет о функциях пользователя (UDF — User Defined Functions). В любом программном продукте для автома тизации процессов тестирования используются два типа функций: встроенные функции и функции пользователя. О встроенных функ циях (то есть ({)ункциях, предоставляемых разработчиком программ ного продукта), являющихся, по сути, программным каркасом авто матизации, достаточно говорилось в предыдущих главах. А что же такое функции пользователя? Как сказано в первой главе, программ ная часть автоматизации процессов тестирования состоит из трех частей. Одной из них является так называемая библиотека функций. В нее входят все функции, определенные пользователем и предна значенные для сокращения количества кода в скриптах путем выне сения повторяюи^ейся функциональности в отдельные программные единицы — фу}1кции пользователя. Функция — это программная единрща, выполняющая определенный код и при этом имеющая воз можность при1И1мать параметры исполнения извне и возвращать ре зультаты исполнения. Синтаксис объявления функции варьируется в зависимости от выбранного языка скриптов, но имеет следующую форму: FUNCTION имяфункции (параметру!. параметр_2,...) код исполнения [возвращаемое значение]
Кчя функции является универсальным идентификатором, позво ляющим вызывать ее из любого участка кода. Параметры функции являются необязательным атрибутом и служат для передачи данных в код исполнения функции. Возвращаемое значение также является необязательным и служит для возвращения информации коду, вы звавшему функцию. Такой информацией может быть как статус вы-
WinRunner
149
полнения кода (успешный/неуспешный), так и результат выполне ния (данные вычисления, результаты логической проверки и т. д.). Функции пользователя предназначены только для одной цели — опти мизации кода. Классическим примером, когда применение функции пользователя является необходимым, служит авторизация пользова теля. Каждый из скриптов, прежде чем любое действие будет выпол нено, должен ввести на странице авторизации имя пользователя и пароль. Применение функции SignInO, принимающей параметры Login и Password, будет оптР1мальным решением в данной ситуации. Теперь рассмотрим, как функция пользователя реализована в «Боль шой тройке» программных продуктов: WinRunner, SilkTest и Rational Robot.
WinRunner TSL определяет функцию пользователя следующим образом: [class] function name ( [mode] parameter... ) { declarations; statements: [return [expression] ] . }
где class — класс функции, public РГЛИ static (см. главу 3, табл. 3.1 «Классы переменных»); mode — тип передаваемого параметра, in, out ИЛИ inout: • in — параметр, значение которого определено вне данной функ ции и будет использовано как передаваемое значение. Может быть как переменной, так и выражением. Является значением по умол чанию каждого из параметров; • out — параметр, значение которого будет определено в данной функ ции. Может быть только переменной; • inout — параметр, значение которого может быть определено как вне данной функции, так и внутри нее. Может быть только пере менной; • return [expression] — возвращаемое значенр1е. Пример. Функция CompareTwoNumbers, принимающая два парамет ра: Fi rst и Second: function CompareTwoNumbers (First. Second) {
150
Глава 8. Функции пользователя i f (First < Second) { return 0; } else { return 1; }
} CompareTwoNumbers(2.1); #Возвращает 1 (WRTRUE)
Функция сравнивает два числа и возвращает О, если First < Second, и 1, если First > Second.
Silkiest 4test представляет следующую реализацию функции пользователя: [scope] [testcase] [return-type] function-id ( [arguments]) statements [return [expression] ]
где scope — класс функции, public или private; testcase — указатель на то, что данная функция является самостоятельным скриптом; return-type — тип возвращаемого значения; return [expression] — возвращаемое значение. Определение передаваемого сообщения имеет следующий синтаксис: [pass-mode] data-type identifier [null] [optional]
где pass-mode — тип передаваемого параметра, in, out или inout: • in — параметр, значение которого определено вне данной функ ции и будет использовано только для чтения; • out — параметр, значение которого будет определено в данной функции; • inout — параметр, значение которого может быть определено как вне данной функции, так и внутри нее; data-type — тип данных передаваемого значения (см. главу 3, табл. 3.2 4Типы данных»); null — флаг принятия null-значений; optional — флаг указания необязательности параметра. Пример. Блок кода определяет функцию CompareTwoNumbers, при нимающую два численных параметра. First и Second:
Rational Robot
151
BOOLEAN CompareTwoNumbers (INTEGER First. INTEGER Second) i f ( F i r s t < Second) return FALSE else return TRUE CompareTwoNumbers(2.1) //Возвращает TRUE
Функция сравнивает два числа и возвращает FALSE, если First < < Second, и TRUE, если First > Second.
Rational Robot SQABasic — единственный из «Большой Тройки», кто реализует до вольно архаичное (с точки зрения автора) разбиение на процедуры и функции. Согласно такой интерпретации, процедура (subroutine) — это функция, которая не возвращает значения. Процедура пользователя определяется следующим образом: [ Static ] [ Private ] Sub name [ ([Optional] arg [ As type] , . . . ) ] [statement^block] End Sub
где Static, Private — определение класса функции; Optional — флаг указания необязательности параметра; type — тип передаваемых данных (см. главу 3, табл. 3.3 «Типы данных»). Пример. Следующий блок кода определяет процедуру, выводя щую: «Hello, World.»: Sub HelloWorld SQALogMessage sqaNone. "Hel 1 о. Worl d."." " End Sub Call HelloWorld
Функция пользователя определяется следующим образом: [ Static ] [ Private ] Function name [ ( [ Optional ]arg [ As type ] . . . . ) ] [ As functype ] name» expression End Function
где Static и Private — определение класса функции; Optional — флаг указания необязательности параметра; type — тип передаваемых данных (см. главу 3, табл. 3.3 «Типы данных»); functype — тип воз вращаемого значения; name» expression — возвращаемое значение.
152
Глава 8. Функции пользователя
Пример. Функция CompareTwoNumbers, принимающая два числен ных параметра, First и Second: FUNCTION CompareTwoNumbers ( F i r s t As Integer. Second As Integer) As Integer I f F i r s t < Second Then CompareTwoNumbers = 1 Else CompareTwoNumbers =0 End I f End Function CompareTwoNumbers(2,1) 'Возвращает 0
Функция сравнивает два числа и First < Second, и О, если First > Second.
возвращает
1,
если
Практический пример 3 Рассматриваемая ситуация: тестирование приложения Pizza Order. Задача тестирования: необходимо написать функцию пользователя, которая бы принимала в качестве параметров таблицу суммирова ния стоимости заказа и имя DAT-файла, хранящего ожидаемые воз вращаемые данные, и сравнивала результаты, указанные в файле, и данные, полученные непосредственно из таблицы. Тест-скрипт: 1. Открыть файл для чтения. 2. Провести выборку и определение данных. 3. Закрыть файл. 4. Проверить, что количество строк в таблице соответствует ожи даемому. 5. Проверить, что количество столбцов в таблице соответствует ожидаемому. 6. Построчно произвести сравнение возвращенных данных с ожи даемыми. 7. Вывести результаты сравнения. Формат *.DAT-файла: Size|Toppings|Price Large|pepperony|2 Largejmushroomsjl.S
практический пример 3
153
Large I meat 12.5 TOTAL I$13
WinRunner Прежде чем написать данную функцию, необходимо создать неболь шую функцию подсчета разделительных флагов в строке: function GetNumChar(sTmp,sChar) { auto с=1; whne(inclex(sTmp,sChar)!=0) { sTmp = substrCsTmp, indexCsTmp, sChar)+l, length(sTmp)indexCsTmp, sChar)): C++:
} return c: } function TableCheckData (HTMLTable. filename) { # Обозначить используемые переменные: auto ExpectedData []: auto bResuU = E_OK: auto i=0: auto c=l: auto line, HTMLRowCount,HTMLColumnCount. HTMLTmp. Tmp: # Открыть файл для чтения: fi1e_open '(fi1ename. FO_MODE_READ): # Провести выборку и определение данных: while(fi1e_getline(filename, 1ine)==E_0K) { ExpectedData [i] = line: i++:
} # Закрыть файл: file_c1ose (filename): # Проверить, что количество строк в таблице соответствует ожидаемому: tbl_get_rows_count(HTMLTablе,HTMLRowCount): if (HTMLRowCount!=i) { tlstepC'Row Count".-1,"Expected table has different
number("&i&") of rows from actual table("&(HTMLRowCount-l)&")"): bResult = -1: } # Проверить, что количество столбцов в таблице соответствует ожидаемому: tbl_get_colscount(HTMLTable,HTMLColumnCount):
154
Глава 8. Функции пользователя
с = GetNumChar(ExpecteclData[0]."|"); i f (HTMLColumnCount!=c) {
tlstepC"Column Count".-1."Expected table has different number of columns("&c&") from actual table("&HTMLC0IumnCount&")"); bResult - -1; } # Построчно произвести сравнение возвращенных данных с ожидаемыми: for(i=l:i<=HTMLRowCount;i++) { Tmp = ""; for(c=l;c<=((6etNumChar(ExpectedData[i-1]."I")
ifCExpectedData [i-l]!= substr(Tmp.2)) { tl__step("Rows Check".-1."Failed!!! "& ExpectedData [i-l]&" vs. "&Tmp): bResult = -1; } } # Вывести результаты сравнения: tl_step("Final Check". bResult."The result of the test is:" & bResult): return bResult: } ПРИМЕЧАНИЕ
По причине слабой поддержки обработки исключительных си туаций в TSL данная функция ожидает, что в случае появления нестандартной ячейки соответствующая информация будет от ражена в тест-файле.
SilkTest Прежде чем написать функцию, необходимо создать небольшую функцию подсчета разделительных флагов в строке: INTEGER GetNumChar (STRING sTmp. STRING sChar) INTEGER c=l while(StrPos(sChar.sTmp)l=0) sTmp = SubStr(sTmp, StrPos(sChar.sTnip)+l. Len(sTmp) StrPos(sChar.sTmp))
практический пример 3
155
C++
return с Саму же функцию определим как метод класса HtmlTable: wind ass Html Table : Html Table BOOLEAN TableCheckData (string filename) HFILE OutputFileHandle ARRAY [3] OF STRING ExpectedData INTEGER i=l,c=l INTEGER HTMLColumnCount, HTMLRowCount STRING line STRING Tmp - "" TABLECELL CurCell BOOLEAN bResult « TRUE list of string IsActualResult // Открыть файл для чтения: OutputFileHandle « FileOpenCfilename, FM_READ) // Провести выборку и определение данных: whileCFileReadLine (OutputFileHandle. line)) if (ArraySize(ExpectedData)
// Закрыть файл: FileClose (OutputFileHandle) // Проверить, что количество строк в таблице соответствует ожидаемому: HTMLRowCount » this.GetRowCountO if ((HTMLRowCount+1) I- ArraySize(ExpectedData)) LogErrorC'Data verification error") LogError("Expected number of rows: "+Str(ArraySize(ExpectedData))) LogError ("Actual number of rows: " + Str(HTMLRowCount+l)) bResult - FALSE // Проверить, что количество столбцов в таблице соответствует ожидаемому: HTMLColumnCount » this.GetColumnCount О if (HTMLColumnCount I- GetNumChar (ExpectedData[l],"|")) LogError("Data verification error") LogError("Expected number of columns: "+Str(GetNumChar(ExpectedDataCl]."|"))) LogError ("Actual number of columns: " + Str(HTMLColumnCount)) bResult - FALSE for(c»l;c<-HTMLColumnCount:C++) Tmp » Tmp + "I" + this.GetColumnName(c) if(ExpectedData [1]!- SubStr(Tmp.2)) LogError("Data verification error") LogError("Expected headers value: "+ExpectedData[i]) LogError ("Actual headers value: " + SubStr(Tmp,2))
1 56
Глава 8. Функции пользователя
bResuU = FALSE // Построчно произвести сравнение возвращенных данных с ожидаемыми: for( i=l: i<=HTMLRowCount: i-н-) Tmp = "" IsActualResult = this.GetRowText(i) for(c=l:c<=HTMLCo1umnCount;C++) do Tmp = Tmp + "I" +lsActualResult[c] except PrintC'Row " + Str(i) +" has " + Str(c-l) +" columns") ifCExpectedData [i+l]!= SubStr(Tmp.2)) LogErrorC'Data verification error") LogErrorC"Expected value: "+ExpectedData[i+l]) LogError ("Actual value: " + SubStr(Tmp.2)) bResult = FALSE // Вывести результаты сравнения: if (!bResult) LogErrorC"Test failed") return bResult
Rational Robot к сожалению, SQABasic предоставляет минимальный набор инстру ментов для работы с таблицами, поэтому нужно будет слегка пере делать файл данных: Формат *.DAT-файла: Size|Toppings!Price Large|pepperony|2 Large I mushrooms 11.5 Large I meat 12.5 TOTAL I$13 Т а к ж е следует несколько изменить алгоритм: FUNCTION TableCheckData (HTMLTableld As String, filename As String) Dim ExpectedData О As String Dim Actual Data О As String Dim i As Integer. bResult As Integer, HTMLRowCount As Integer Dim sLine As String. iText As String i= bResult =1 '$CStrings ReDim ExpectedData (1 to 4) ReDim ActualData (1 to 4) ' Получить информацию о таблице и записать ее в файл: SQAGetProperty "Type=HTMLTabl е;HTMLId=''+HTMLTabl eld. "innerText". iText Open "C:\TEMP\templ.dat" For Output As #1 Print #1, iText
Практический пример 3
157
Close #1 * Открыть тест-файл для чтения: Open filename For Input As #2 ' Провести выборку и определение данных: Do While Not Eof(l) Line Input #2, sLine If UBound(ExpectedData) ExpectedData(1) Then SQALogMessage sqaFail, "Different number of columns", "" bResult = 0 End If ' Построчно произвести сравнение возвращенных данных с ожидаемыми: For i=l to СInt(HTMLRowCount) If ActualData(i) <> ExpectedData(i) Then SQALogMessage sqaFail, "Data verification error", " "
158
Глава 8. Функции пользователя
SQALogMessage sqaNone "Expected value: + ExpectedData(i) SQALogMessage sqaNone "Actual value: " + ActualData(i) . bResult = 0 End If Next I * Вывести результаты сравнения: If bResult = 0 Then SQALogMessage sqaFail Test failed" End If TableCheckData = bResult End Function
Глава 9 Управление процессом исполнения
в этой главе поговорим об управлении процессом исполнения. Что понимаем под этим термином? Представим, что вы тестируете неболь шую страницу, позволяющую быстро пересчитывать рубли в евро. Элементарный интерфейс — две строки ввода и кнопка подтвержде ния. Ничего особенного, верно? Большинство автоматизированных тестов свободно уместится в рамках одного скрипта. А теперь пред положим, что эта страница является частью огромного банковского приложения. Запись всех автоматизированных тестов в один файл становится просто бессмысленной! Тестирование различных частей приложения требует различных тестов, функций, а зачастую и раз личных библиотек объектов. Для таких случаев и существует управ ление процессом исполнения, то есть возможность выполнить различ ные тесты из одного мастер-скрипта и/или подгрузить соответствую щие библиотеки функций и объектов. Собственно само управление процессом исполнения можно разде лить на три части: 1. Вызов тест-скриптов из мастер-скрипта. 2. Загрузка/выгрузка библиотеки функций. 3. Загрузка/выгрузка библиотеки объектов. Рассмотрим каждое из них детально.
160
Глава 9. Управление процессом исполнения
Вызов тест-скриптов из мастер-скрипта WinRunner TSL предоставляет следующую функцию вызова скрипта: call test_name ( [ parameterl. parameter2, ... parametern ]): где test_name — имя скрипта; parametern — параметры теста. Функция вызывает скрипт test_name с параметрами parametern. Пример. Исполнение скрипта t e s t l : call "c:\\order_page\\test_l" О;
SilkTest 4Test предлагает несколько отличную технологию вызова тестов. Каждый логически законченный скрипт находится внутри конструк ции testcase и может быть вызван как сам по себе, так и в порядке очереди исполнения. Конструкция имеет следующий синтаксис: testcase test_name О [appstate appstate_name].
где test_name — имя скрипта; appstatename — параметры теста. Функцрш вызывает скрипт testname, приводящий тестируемое при ложение в состояние appstate_name. Пример. Исполнение скрипта test_l: testcase test_l О
Appstate — скрипт, определяющий состояние тестируемого приложе ния и определяемый в inc-файле. Appstate имеет следующий синтак сис описания: appstate appstatel О [basedon appstate2]. statements
где appstatel — имя скрипта состояния; appstate2 — имя родитель ского скрипта состояния. Пример. Следующая строка кода определяет скрипт состояния MyAppState на основе MyBaseState: appstate MyAppState О basedon MyBaseState W код исполнения
Загрузка/выгрузка библиотеки функций
161
Rational Robot SQABasic имеет функцию вызова скрипта, следующего вида: CallScript scripts
где scripts — имя скрипта. Функцрш вызывает скрршт scripts. Пример. Следующая строка кода вызывает к исполнению скрипт test_l: CallScript "с:\order_page\test_l"
Загрузка/выгрузка библиотеки функций WinRunner Функция загрузки библгютеки функций от TSL имеет следующий вид: load ( module_name [Л/О [ Л / О ] ] ):
где module_name — имя библрютеки функций. Функция вызывает библиотеку функций test_name. Первая пара «1/0» определяет, какой модуль загружается, системный (1) или компили руемый (0) (значение по умолчанию — 0). Вторая пара «1/0» опре деляет, отображать (0) или пет (1) содержимое модуля на экране (значение по умолчанию — 0). Пример. Следующая строка кода загружает библиотеку функций my_function_1ib: load ("my_function_lib");
Функция выгрузки библиотеки функций от TSL имеет следующий синтаксис: unload ( [ module | test [ , function_name ] ] );
где module|test — имя выгружаемой библиотеки функций | скрипта; functionname — имя выгружаемой функции. Функция выгружает библиотеку функций module|test. Если functionname указана, то выгружается только эта функция. Пример. Следующая строка кода выгружает библиотеку функций my_function_lib: unload ( " m y f u n c t i o n l i b " ) :
162
Глава 9. Управление процессом исполнения
Silkiest Синтаксис функции загрузки библиотеки функций 4test: use "FileName"
где FileName — имя библиотеки функций. Функция включает библиотеку функций FileName в список компи ляции. Пример. Загрузка библиотеки функций my_functionJib: use "my__f unction J i b "
Rational Robot Функция загрузки библиотеки функций SQABasic имеет следующий синтаксис: '$Include: "filename"
где filename — имя библиотеки функций. Функция включает библиотеку функций filename в список компиля ции. Пример. Следующая строка кода загружает библиотеку функций my^functionjib: '{Include: " my_functionJib "
Загрузка/выгрузка библиотеки объектов WinRunner Синтаксис функции загрузки библиотеки объектов TSL: GUIJoad ( file_name ) ;
где file^name — имя библиотеки объектов. Функция вызывает библиотеку объектов file^name. Пример. Следующая строка кода загружает библиотеку объектов my_obj_lib: GUIJoad ("my^objjib"):
Для выгрузки библиотеки объектов TSL предлагает следующую функцию:
Загрузка/выгрузка библиотеки объектов
163
GUI_unload ( file ):
где file — имя выгружаемой библиотеки объектов. Функция выгружает библиотеку объектов file. Пример. Строка кода выгружает библиотеку объектов my_obj_lib: GUI^unload ("Fny__objJib ");
SilkTest Функция загрузки библиотеки объектов 4Test: use "FileName"
где FileName — имя библиотеки объектов. Функция включает библиотеки объектов FileName в список компи ляции. Пример. Следующая строка кода загружает библиотеку объектов my__objJib: use "my_objJib"
Rational Robot Следует еще раз напомнить, что Rational Robot не использует стан дартные библиотеки объектов и потому подобных функций не имеет.
Приложение А Работа о нестандартными объектами в SilkTest
в этом приложенхп! поговорим о пестапдартпых классах (Custom Classes) и о том, какрге средства для работы с ними предоставляет SilkTest. Нестандартные классы появляются тогда, когда для созда ния интерфейса программисты используют нестандартные объекты (например, custom HTML tags) или стандартные объекты нестандарт ным образом (например, ComboBox с возможностью вызова специаль ного меню щелчком правой кнопки мыши на элементе списка). В про цессе работы с такими объектами возникают следующие ситуации: 1. Набор графических объектов распознается как один объект. 2. Объект не распознается вообще и требует написания методов ра боты с ним с нуля. 3. Объект распознается как нестандартный класс, но может быть пе редекларирован как стандартный. Рассмотрим эти ситуации подробнее.
Набор графических объектов распознается как один объект Примером подобной ситуации может служить работа панели инст рументов. Зачастую панели инструментов, написанные на ActiveX или VisualBasic, распознаются как один объект. При этом все кноп ки на панели прекрасно работают и являются отдельными объекта ми. Лучшим решением проблемы при условии, что все кнопки оди накового размера, станет разбивка объекта. Предположим, имеется
Работа с нестандартными объектами в Silkiest
165
панель инструментов из семи кнопок, стоящих в ряд, со следующим описанием: CustomWin PaintWindowl mswdos tag "[ PaintWindow]#l" Сделать из нее семь кнопок можно следующим образом: CustomWin FileOpen mswdos tag "[ PaintWindow]#l(l:7. 1:1)" CustomWin Printer mswdos tag "[ PaintWindow]#l(2:7, 1:1)" CustomWin Preview mswdos tag "[ PaintWindow]#l(3:7, 1:1)" CustomWin Save mswdos tag "[ PaintWindow]#l(4:7, 1:1)" CustomWin Cut mswdos tag "[ PaintWindow]#l(5:7. 1:1)" CustomWin Copy mswdos tag "[ PaintWindow]#l(6:7. 1:1)" CustomWin Paste mswdos tag "[ PaintWindow]#l(7:7. 1:1)" Теперь, чтобы нажать на кнопку Сохранить панели инструментов, бу дет достаточно следующего кода: Save.ClickO.
Объект не распознается вообще и требует написания методов работы с ним с нуля Предположим, существует нестандартный класс CustomEditBox, необ ходимо его определить и создать методы работы с ним. Для начала определим его как дочерний класс класса AnyWin (базо вый класс для любого графического элемента в SilkTest): wind ass CustomTextField : AnyWin / / теперь определим метод очистки содержимого объекта: void ClearTextO TypeKeys("") TypeKeys("") TypeKeys("") / / определим метод печати в объект: void SetMultiText (string sText) this. ClearTextO TypeKeys(sText) / / определим метод копирования выделенного текста в буфер обмена: l i s t of string GetMultiSelText (string sText) Clipboard.SetTextO TypeKeys("") return (Clipboard.GetTextO)
166
приложение А. Работа с нестандартными объектами в Silkiest
/ / определим метод копирования всего текста в буфер обмена: l i s t of string GetMultiSelText (string sText) Clipboard.SetTextO TypeKeysC"") TypeKeys("") TypeKeys("") return (Clipboard.GetTextO)
Новый UI-класс (класс пользовательского интерфейса) готов к упот реблению. Объект распознается как нестандартный класс, но может быть передекларирован как стандартный Данная ситуация возникает, когда нестандартный объект был изме нен настолько, чтобы быть распознаваемым как нестандартный, но при этом он может использовать все методы своего «стандартного» воплощения. Предположим, имеется CustomListBox и надо передеклари ровать его как стандартный ListBox, принадлежащий окну BrowserChi Id: CustomWin CustomListBox tag "[BrowserChi1d]#l\[ListBox]#l"
Приложение Б Работа с нестандартными объектами в WinRunner
в этом приложении поговорим о нестандартных классах (Custom Classes) и о том, какие средства WinRunner предоставляет для рабо ты с ними. Нестандартные классы появляются тогда, когда для соз дания интерфейса пользователя программисты используют нестан дартные объекты (custom HTML tags и т. п.) или используют стан дартные объекты нестандартным образом (ComboBox с возможностью вызова специального меню щелчком правой кнопки мыши на элемен те списка). WinRunner дает возможность обрабатывать следующие ситуации: 1. Объект не распознается вообще и требует написания методов ра боты с ним с нуля. 2. Объект имеет текстовый определитель (identifier), который не значительно изменяется с каждым вызовом программы тестиро вания. 3. Объект распознается как нестандартный класс, но может быть пе редекларирован как стандартный.
Объект не распознается и требует написания методов работы с ним с нуля в силу особенностей своей закрытой архитектуры и процедурной архитектуры TSL WinRunner не позволяет работать с подобными объектами, используя только ресурсы инструмента. Для того чтобы создать новый тип объекта и определить функции работы с ним, не обходимо написать DLL на C++ или другом языке высокого уровня.
168
Приложение Б. Работа с нестандартными объектами в WinRunner
По сути, вам необходимо будет написать собственную надстройку к WinRunner. Так как описание подобного процесса займет не один десяток страниц, здесь оно приводиться не будет. Скажем лишь, что это вполне возможно, но потребует много времени на разработку, к тому же нужен уровень знаний профессионального инженераавтоматизатора (а также знания Win32API, архитектуры Windows и хотя бы одного языка высокого уровня).
Объект имеет текстовый определитель, который незначительно изменяется с каждым вызовом программы тестирования Предположим, существует нестандартный класс CustomWin и его mswclass постоянно меняется с AfxWnd42ud то на AfxWnd32ud, то на AfxWnd42pd. Вот как можно описать этот класс в GUI-файле: {class: window.label: \"!Application Designer.*\".MSW_class: \"!Afx.*\"}
TO есть можно заменить часть описания регулярным выражением.
Объект распознается как нестандартный класс, но может быть передекларирован как стандартный Данная ситуация возникает, когда нестандартный объект был изме нен настолько, чтобы быть распознаваемым как нестандартный, но при этом он может использовать все методы своего «стандартного» воплощения. Предположим, имеется CustomListBox и надо передекла рировать его как стандартный ListBox, принадлежащий окну BrowserChild. Для того чтобы он распознавался как ListBox, перед записью элемента в GUI-файл должен быть выполнен следующий код: set_class_map("CustomListBox"." ListBox"):
Приложение В Автоматизация приложения Pizza Order средствами SilkTest и WinRunner
На примере приложения Pizza Order покажем основные составляю щие автоматизации и приведем конкретные программные решения. Это приложение никоим образом не претендует на звание настояще го бизнес-приложения и преследует единственную цель — предоста вить достаточную базу для проведения комплексной автоматизации процессов тестирования.
Бизнес-спецификация Программное решение должно представлять собой интернет-страни цу, дающую пользователю возможность заказать и оплатить пиццу. Пицца может быть трех возможных размеров и содержать до трех различных видов начинки.
Функциональная спецификация Приложение должно иметь две страницы: страницу заказа и стра ницу оплаты.
170
приложение В. Автоматизация приложения Pizza Order
1. На странице заказа должны присутствовать следующие эле менты: О Список возможных размеров пиццы (значение по умолчанию — null). Можно выбрать только один размер. Варианты выбора: Large, Medium и Small. О Список возможных начинок пиццы (значение по умолчанию — null). Можно выбрать одну начинку, несколько начинок или ни одной. Варианты выбора: Реррегопу, Mushrooms и Meat. о Управляющие элементы для вычисления суммы заказа, очист ки формы заказа и перехода на страницу оплаты. О Таблица суммы заказа. О Элемент установления связи с администрацией приложения. 2. Пользователь не должен иметь возможности перейти к странице оплаты, не сделав заказ. 3. Страница оплаты должна иметь следующие элементы: О Поле ввода полного имени владельца кредитной карты. О Список принимаемых типов кредитных карт (Visa, Master Card, American Express и Discover). О Поле ввода номера кредитной карты. О Элементы определения срока действия кредитной карты. О Поле ввода адреса доставки пиццы и отсылки копии счета. О Управляющие элементы для оплаты заказа и очистки формы оплаты заказа. 4. Пользователь получает уведомление в следующих случаях: О Превышен баланс по его кредитной карте. О Номер кредитной карты не соответствует образцу данного типа карты. О Истек срок действия кредитной карты. О Какое-либо из полей ввода не заполнено.
Техническая спецификация Приложение будет иметь следующий интерфейс:
171
функциональная спецификация
Страница заказа: Toppings
Pizza Туре $) Large [$7.00] О Medium [S6.00]
m Pepperony [$2.00] 2!Mushrc.omi[$1.50] El Meat [$2.50]
1 О $тЛ [$5.00]
\:ъй^\^ш,<Ш.^.-1
tvR»frf>h:,|
Size
Toppiii{s
Large
pepperony
Price 2
Large
mushroomt
15
Large
meat
25
$13
TOTAL
Web Admm: soffieone(2).3orney.te com
• Страница оплаты: Name:
;
Credit Card Type:
Exp.Date
I>^^^IZZI
?Ftbruary ii March iiApril
w:':i
Ш
Number:
2007 v 1
;i!i^:i|
Address
{. Subrntt,}
К о д страницы з а к а з а Pizza Ordering Page
|J?efre9h-|
172
Приложение В. Автоматизация приложения Pizza Order
<script type="text/jscript"> var Asize=new Array(l) var Atoppings = "" var Total = 0 function GetSize(size) { Asize[0]=size } function GetToppingsO { Atoppings = "" i f(document.forms.PreOrder.pepperony.checked==true) { Atoppings=Atoppings+"pepperonyI|" } i f( document. forms. PreOrder. mushrooms. checked=true) ( Atoppings=Atoppings+"mushrooms||" } i f(document.forms.PreOrder.meat.checked==true) { Atoppi ngs=Atoppi ngs+"meat" } } function GetPr1ce(v) { switch(v) { case "Large": return 7 break case "Medium": return 6 break case "Small": return 5 break case "pepperony": return 2 break case "mushrooms": return 1.5 break case "meat": return 2.5
функциональная спецификация default: return О } } function deleteRowsO { var x=document.getE1ementById('OrderTbl').rows.1ength if (x>l) { for(i = 1; i <x : i++) { document.getElementByldC'OrderTbl').deleteRow(l) } } } function insRowsO { deleteRowsO GetToppingsO Total = GetPrice(Asi2e[0]) topArr = Atoppings.splitC'l |") for(i=0:i
{
if(topArr[i]!="") { var x=document.getElementByldC'OrderTbl').insertRow(i+l) var y=x.insertCell(0) var z=x.insertCell(l) var t=x.insertCell(2) у.innerText=Asize[0] 2.i nnerText=topArr[i] t.innerText=GetPrice(topArr[i]) Total = Total + GetPrice(topArr[i]) document.getElementByldC'OrderTbl').rows[i+l].align="center" } } insTotalO } function insTotalO { var i=document.getElementByldC'OrderTbl').rows.1ength var x=document.getElementByldC'OrderTbl').insertRow(i) var y^x.insertCell(O) var z=x.insertCell(l) y.innerText="TOTAL" z.innerText="$"+Total var n=document.getElementByldC'OrderTbl').rows[i].cells
173
174
приложение В. Автоматизация приложения Pizza Order
n[l].colSpan="2" document.getElementByldC'OrderTbl').rows[i].ali gn="center" }
Страница оплаты Pizza Ordering Page <script type«"text/jscript"> function VerifylnfoO { var d = new DateO var chd » new Date(document.forms.ConfirmOrder.Month.value+- 1. "+document.forms.Confi rmOrder.Year.value) i f (document. forms. Conf i rmOrder. name. val ue="'") { alertC'You did not specify name") } i f(document.forms.Confi rmOrder.numb.value«="")
175
176
Приложение В. Автоматизация приложения Pizza Order
{ alertC'You did not specify Credit Card Number") }
i f (document. forms. Conf i rmOrder .Address. val ue="") { alert("You did not specify Address") }
if(((document.forms.ConfirmOrder.numb.value^l6)!=0)&&(document.forms.С onfirmOrder.CardType.value!="amexpress")) { alert("Incorrect Card Number. Valid format is 1234 5678 9012 3456") } if (((document.forms.ConfirmOrder.numb.value^l5)!=0)&&(document.forms.C onf i rmOrder. CardType. val u e = " amexpress")) { alert("Incorrect Card Number. Valid format is 1234 567890 12345") } if(d>=chd) { alert("Incorrect Date. Your card has expired") } }
Тестовая документация Тест-кейс: Выбор параметров
1. Выберите Large из списка Pizza Туре. 2. Поочередно выберите каждую возможную комбинацию вариан тов начинок в списке Toppings (невыбор рассматривается как одна из возможных комбинаций), выполняя проверку после каждого варианта. 3. Выполните шаги 1 и 2 для варианта Medium из списка Pizza Туре. 4. Выполните шаги 1 и 2 для варианта Small из списка Pizza Туре. Тест-кейс: Проверка почтового клиента
1. Кликните на ссылке для отправки почты. 2. Проверьте, что почтовый клиент запущен с правильным адресом. Тест-кейс: Проверка вычислений
1. Выберите вариант Large из списка Pizza Туре. 2. Поочередно выберите каждую возможную комбинацию в списке Toppings (невыбор рассматривается как одна из возможных оп ций) и после каждой комбинации выполните проверку данных, нажимая кнопку Calculate Order. 3. Выполните шаги 1 и 2 для варианта Medium из списка Pizza Туре. 4. Выполните шаги 1 и 2 для варианта Small из списка Pizza Туре. Тест-кейс: Проверка выполнения очистки
1. Выберите вариант Large из списка Pizza Туре. 2. Выберите ваарианты Реррегопу, Mushrooms и Meat в списке Toppings.
функциональная спецификация
179
3. Нажмите кнопку Refresh. 4. Проверьте, что страница вернулась в исходное состояние. Тест-кейс: Проверка перехода на страницу оплаты
1. 2. 3. 4.
Выберите вариант Large из списка Pizza Туре. Выберите варианты Реррегопу, Mushrooms и Meat в списке Toppings. Нажмите кнопку Оплата (рисунок доллара). Убедитесь, что появилась страница оплаты.
Тест-кейс: Проверка появления сообщений о незаполненных полях ввода
1. Нажмите кнопку Submi't. 2. Проверьте, появилось ли сообщение «You did not specify name». 3. Проверьте, появилось ли сообщение «You did not specify Credit Card Number». 4. Проверьте, появилось ли сообщение «You did not specify Address». Тест-кейс: Проверка появления сообщения об истекшем сроке действия кредитной карты
1. 2. 3. 4.
Введите Иуа Vinnichenko в поле Name. Выберете вариант Visa в списке Credit Card Type. Введите 1234567890123456 в поле Number. Выберите варианты January и 2004 в списке Ехр. Date.
5. Введите 1600 Pennsylvania Avenue NW Washington, DC 20500 USA в поле Address.
6. Нажмите кнопку Submit. 7. Убедитесь, что появилось сообщение «Incorrect Date. Your card has expired». Тест-кейс: Проверка появления сообщений о неправильном формате номера кредитной карты VISA/Master Card/Discover Card
1. 2. :3. 4.
Введите Иуа Vinnichenko в поле Name. Выберете Visa в списке Credit Card Type. Введите 1234567890123 в поле Number. Выберите варианты January и 2007 в списке Ехр. Date.
180
Приложение В. Автоматизация приложения Pizza Order
5. Введите 1600 Pennsylvania Avenue NW Washington, DC 20500 USA в поле Address. 6. Нажмите кнопку Submit. 7. Проверьте, появилось ли сообщение «Incorrect Card Number. Valid format is 1234 5678 9012 3456». 8. Выполните шаги 1-7 для вариантов Master Card и Discover Card. Тест-кейс: Проверка появления сообщений о неправильном формате номера кредитной карты American Express 1. Введите Иуа Vinnichenko в поле Name. 2. Выберите American Express в списке Credit Card Type. 3. Введите 1234567890123 в поле Number. 4. Выберете варианты January и 2007 в списке Ехр. Date. 5. Введите 1600 Pennsylvania Avenue NW Washington, DC 20500 USA в поле Address. 6. Нажмите кнопку Submit. 7. Убедитесь, что появилось сообщение «Incorrect Card Number. Valid format is 1234 567890 12345».
Структура автоматизации WinRunner Библиотека функций (UDF) function GetNumChar(sTmp,sChar) { auto c=l; while(index(sTmp,sChar)l=0) { sTmp = substr(sTmp. indexCsTmp, sChar)+l. length(sTmp)-index(sTmp. sChar)); C++: } return c: } function TableCheckData (HTMLTable, filename) { # Обозначить используемые переменные: auto ExpectedData []; auto bResult = E OK;
Структура автоматизации
181
auto i=0: auto c=l; auto line, HTMLRowCount.HTMLColumnCount, HTMLTmp, Imp; # Открыть файл для чтения: file^open (filename, FO_MODE_READ); # Провести выборку и определение данных: whileCfile getline(filename, line)=E_OK) { ExpectedData [i] = line; i++;
} # Закрыть файл: file^close (filename): # Проверить, что количество строк в таблице соответствует ожидаемому: t Ы __get_,rows_count (HTMLTabl е, HTMLRowCount); if (HTMLRowCount!=i) { tl__step("Row Count",-1,"Expected table has different number("&i&") of rows from actual table("&(HTMLRowCount-l)&")"): bResult = -1: } # Проверить, что количество столбцов в таблице соответствует ожидаемому: tbl jet_col s_.count (HTMLTabl e, HTMLCol umnCount); с = GetNumChar(ExpectedData[0],"|"); if (HTMLColumnCount!=c) { tl_step("Column Count",-1,"Expected table has different number of columns("&c&") from actual table("&HTMLColumnCount&")"): bResult = -1; } # Построчно произвести сравнение возвращенных данных с ожидаемыми: for( i=l: i<=HTMLRowCount; i-н-) { Tmp = ""; for(c=l;c<=((GetNumChar(ExpectedData[i-1],"|")
182
Приложение В. Автоматизация приложения Pizza Order
# Вывести результаты сравнения: tl__step("Final Check", bResult."The result of the test i s : " & bResult):
return bResult; } public function CIoseAllBrowsers0 { auto BrowserWindow; CurrentBrowserWindow = "{class: window, MSW_class: browser_main_window, NSTitle: \"Browser Main WindowX", location:0}" whi 1 e (win_exists(BrowserWindow)=E_OK) { win_close( BrowserWindow); } } Библиотека объектов (AppGUIMap.gui)
PizzaOrderingPage: { class: window, MSW_class: html_frame, html^name: "Pizza Ordering Page" } { rtree_state: open, ltree_state: close }
Pi zzaOrderi ngPage.Address: { class: e d i t . MSW_class: html__edit, html_name: Address }
Pi zzaOrderi ngPage.CalculateOrder: { class: push_button, MSW^class: html_push_button, html_name: "Calculate Order" }
Pi zzaOrderi ngPage.CardType: { class: list. MSW^class: html^combobox, location: 0 } Pi zzaOrderi ngPage.Confi rmOrder:
Структура автоматизации
{ class: object, MSW__class: html_rect. html_name: "buck.jpg" } Pi zzaOrderi ngPage.Large: { class: radio_button, MSW^class: html__radio_button. html^name: type. part_value: Large } Pi zzaOrderi ngPage.Mai 1 Li nk: { class: object, MSW_class: html_text_link,
html_name: "someone@somesite.com" } Pi zzaOrderi ngPage.Medi urn: { class: radiobutton, MSWclass: html_radio_button, html_name: type, part_value: Medium }
Pi zzaOrderi ngPage.Month: { class: list, MSW_class: htmljistbox }
Pi zzaOrderi ngPage.Refresh: { class: push_button, MSW_class: html_push_button, html_name: Refresh } Pi zzaOrderi ngPage.Smal1: { class: radio_button, MSWclass: htmlradio^button. html^name: type, partvalue: Small }
Pi zzaOrderi ngPage.Submi t: { class: push_button, MSWclass: html_push_button.
183
184
Приложение В. Автоматизация приложения Pizza Order
html_name: Submit }
Pi zzaOrderi ngPage.SummaryTab!e: { class: object, MSW^class: html__table. location: 1 } Pi zzaOrderi ngPage.Year: { class: list. MSW class: html^combobox. location: 1 } Pi zzaOrderi ngPage.meat: { class: check_button. MSW_class: html_check_button, html_name: meat. part_value: on } Pi zzaOrderi ngPage.mushrooms: { class: check_button. MSW_class: html_check_button. html_name: mushrooms, part_value: on } Pi zzaOrderi ngPage.name: { class: edit. MSW^class: html__edit. html_name: name } Pi zzaOrderi ngPage.numb: { class: edit. MSW_class: html_edit. html_name: numb } Pi zzaOrderi ngPage.pepperony: { class: check^button. MSWclass: html^checkbutton. html_^name: pepperony. part_^value: on }
Структура автоматизации WarningMsg: { class: window. label: "Microsoft Internet Explorer" MSW^class: Dialog } { rtree^state: open, ltree_state: open } WarningMsg.OK: { class: push_button, label: OK } WarningMsg.Text: { class: static_text, MSWJd: 65535. value: "!*." } Библиотека скриптов TestPlan load ("UDF"): guiJoad("AppGUIMap"): call "SelectOptions"(); call "CheckLink"(): call "CheckCalc"(): call "CheckTypeClear"(); cal1 "GoToPaymentPage"(): call "CheckWarnings"(); call "CheckCCExpired"(): call "CheckVisaFormat"(): cal1 "CheckAEFormat"(): OpenOrderPage if ((win_exists("PizzaOrderingPage")!=E__OK) || (Ob j_exi sts( "Cal cul ateOrder") !=E__OK)) { CloseAllBrowsersO: webbrowser invoke ( IE, "C:\\Temp\\index.html" ); }
185
186
Приложение В. Автоматизация приложения Pizza Order
OpenPaymentPage i f ((win_exists("PizzaOrderingPage")!=E_OK) || (obj_exists("Submit")!=E_OK)) { CloseAllBrowsersO: web__browser_invoke ( IE, "C:\\Temp\\calc.htm1" ) ; } SelectOptions call "OpenOrderPage"(): set_window("PizzaOrderingPage"); for(i=l:i<=3:i++) { button_set("Large", ( i = l ) ? l : 0 ) ; button_set("Medium". ( i = 2 ) ? l : 0 ) : button_set("Small", ( i = 3 ) ? l : 0 ) : for(c=0:c<=6:c++) ( button_set("meat".(c=l || c=-4 || c==5)?l:0);
button_set("mushrooms". (c=2 || c>=4)?l:0): button_set("pepperony". (c=3 || c = 4 || c==6)?l:0); } } CheckLink call "OpenOrderPage"(); set_window("PizzaOrderingPage"): web_link_click("MailLink"); ### Проверка почтового клиента (здесь не описывается, так как зависит от конфигурации системы) CheckCalc arrCount = 0: filename [ ] = {"CWTestDataWExpectedl". "C\\TestData\\Expected2". "CWTestDataWExpectedS". "C\\TestData\\Expected4". "CWTestDataWExpectedS", "C\\TestData\\Expected6". "CWTestDataWExpected?". "CWTestDataWExpectedS". "C\\TestData\\Expected9". "CWTestDataWExpectedlO". "eWTestDataWExpectedll", "C\\TestData\\Expectedl2". "CWTestDataWExpectedlS". "CWTestDataWExpectedl". "CWTestDataWExpectedlS". "C\\TestData\\Expectedl6". "CWTestDataWExpectedl?". "CWTestDataWExpectedlS". "C\\TestData\\Expectedl9". "C\\TestData\\Expected20". "C\\TestData\\Expected21"};
Структура автоматизации
call "OpenOrderPage"(); set_window("PizzaOrderingPage"); for(i=l;i<=3;i-H-)
{ button_set("Large", (i=l)?l;0); button_set("Medium", (i==2)?l:0): button__set("Small", (i«=3)?l:0); for(c=0;c<»6:c-H-) { button_set("meat".(c=l || c = 4 || c==5)?l:0); button_set("mushrooms", (c==2 || c>=4)?l:0): button_set("pepperony", (c=3 jj c==4 || c=6)?l:0); button_press("CalculateOrder"); bResult = TableCheckData ("SummaryTable", filename[arrCount]); tl_step("CheckCalc".bResult, fi1ename[arrCount]); arrCount++; } } CheckTypeClear call "OpenOrderPage"(): bResult = 0; set_window("P1zzaOrderingPage"); button_set("Large".ON):
button_set("meat".ON); button_set("mushrooms",ON): button_set("pepperony",0N); button_press("Refresh"); button_get_state("Large",state): if (state = 0 N ) bResult = -1: button_get_state("Medium",state); if (state = 0 N ) bResult = -1; button_get_state("Smal1".state): if (state = 0 N ) bResult = -1; button_get_state("meat".state): if (state = 0 N ) bResult = -1; button_get_state("mushrooms",state); if (state = 0 N ) bResult = -1: button_get_state("pepperony",state): if (state =<)N) bResult = -1:
187
188
приложение В. Автоматизация приложения Pizza Order
t1_step("CheckTypeClear", bResult." CheckTypeClear") GoToPaymentPage
call "OpenOrderPage"(); set_window("PizzaOrderingPage"): button_set("Large".ON); button_set("meat",0N); button_set("mushrooms".ON); button_set("pepperony",0N); webJmage_click("ConfirmOrder". 9, 12); i f ((win_exists("PizzaOrderingPage")=E_OK) &&
(Obj^exi Sts("Submi t")!=E_OK)) { tl_step("GoToPaymentPage",-l."Page did not show up."); CheckWarnings cal1 "OpenPaymentPage"(); setwi ndow( "Pi zzaOrderi ngPage"); button_press("Submit"); if (win_exists("WarningMsg".5)=E__0K)
{ set_window("WarningMsg"); if (obj_exists("{class: static_text, MSWJd: 65535. value: \"You did not specify name\"}")=E_OK) tl_step("CheckWarnings",0,"You did not specify name message appeared") else tl_step("CheckWarnings".-l."You did not specify name message did not appear"); button_press("OK"); } else { tl_step("CheckWarnings",-l."You did not specify name message did not appear"); } i f (win__exists("WarningMsg".5)=E^0K) { set_window("WarningMsg"); i f (obj_exists("{class: static^text. MSWJd: 65535. value: \"You did
not specify Credit Card Number\"}")=E__OK) tl_step("CheckWarnings",0." You did not specify Credit Card Number message appeared"); else tl_step("CheckWarnings".-l." You did not specify Credit Card Number message did not appear");
Структура автоматизации
189
buttonjress( "OK"): } else { tl_step("CheckWarnings".-l." You did not specify Credit Card Number message did not appear"): } if (win_exists("WarningMsg",5)==E_0K) { set_wi ndow("Warni ngMsg"): if (obj_exists("{class: static^text. MSW_id: 65535. value: \"You did not specify Address\"}")=E_OK) tl__step("CheckWarnings".0,"You did not specify Address message appeared"): else tl_step("CheckWarnings",-l."You did not specify Address message did not appear"): button_press("OK"): } else { tl__step("CheckWarnings",-l."You did not specify Address message did not appear"): } CheckCCExpired cal1 "OpenPaymentPage"(): $et_wi ndow("Pi zzaOrderi ngPage"): edit__set("name", "Ilya Vinnichenko"): 1 ist_selectjtem( "CardType". "Visa"): edit_set("numb"."1234567890123456"): 1ist_select_item("Month"."January"): 1ist_select_item("Year"."2004"): edit__set("Address"."1600 Pennsylvania Avenue NW Washington. DC 20500 USA"): button_press("Submit"): if (winexists("WarningMsg".5)==E_0K)
{ set^window("WarningMsg"): i f (obj_exists("{class: static^text. MSWJd: 65535. value: \"Incorrect Date. You card has expired\"}")==E_OK) tl__step("CheckWarnings".0."Incorrect Date. You card has expired message appeared") else tl__step("CheckWarnings".-l." Incorrect Date. You card has expired did not appear"):
190
Приложение В. Автоматизация приложения Pizza Order
button_press("OK"); } else { tl_step("CheckWarnings",-l," Incorrect Date. You card has expired did not appear"): } CheckVisaFormat cal1 "OpenPaymentPage"(); set_window("PizzaOrderingPage"); edit_set("name","Ilya Vinnichenko"): list_select_item("CardType","Visa"); edit_set("numb"."1234567890123"); 1 i st__sel ect J tem( "Month", "January"); list__selectJtem("Year","2007"); edit__set("Address","1600 Pennsylvania Avenue NW Washington, DC 20500 USA"): button_press("Submit"); i f (win_exists("WarningMsg", 5)=E__0K)
{ set__wi ndow( "Warni ngMsg"): if (obj_exists("{class: static_text, MSW_id: 65535, value: \" Incorrect Card Number. Valid format is 1234 5678 9012 3456\"}")=E_0K) tl_step("CheckWarnings".0," Incorrect Card Number. Valid format is 1234 5678 9012 3456 appeared") else tl_step("CheckWarnings",-l," Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear"): button_press("OK"): } else { tl_step("CheckWarnings",-l." Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear"): } set_window("PizzaOrderingPage"): button_press("Refresh"): edit_set("name"."Ilya Vinnichenko"): list_select_item("CardType","Discover Card"): edit_set("numb"."1234567890123"): list_select_item("Month","January"): list_select_item("Year"."2007"): edit_set("Address"."1600 Pennsylvania Avenue NW Washington, DC 20500 USA"):
Структура автоматизации
191
button_press("Submit"); if (win_exists("WarningMsg",5)==E_0K) { set_wi ndow("Warni ngMsg"): if (obj_exists("{class: static_text. MSWJd: 65535. value: \" Incorrect Card Number. Valid format is 1234 5678 9012 3456\"}")=E_0K) tl_step("CheckWarnings".0," Incorrect Card Number. Valid format is 1234 5678 9012 3456 appeared") else tl_step("CheckWarnings",-l." Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear"): button_press("0K"): } else { tl_step("CheckWarnings",-l." Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear"): } set^wi ndow("Pi zzaOrderi ngPage"): button_press("Refresh"): edit_set("name"."Ilya Vinnichenko"): list_select_item("CardType","Master Card"): edit_set("numb"."1234567890123"): 1 ist__select_item( "Month". "January"): list_selectjtem( "Year", "2007"): edit_set("Address"."1600 Pennsylvania Avenue NW Washington. DC 20500 USA"): button_press("Submit"): if (win_exists("WarningMsg".5)=E_0K) { set_window("WarningMsg"): if (obj_exists("{class: static_text, MSWJd: 65535, value: \" Incorrect Card Number. Valid format is 1234 5678 9012 3456\"}")==E_0K) tl_step("CheckWarnings",0," Incorrect Card Number. Valid format is 1234 5678 9012 3456 appeared") else tl_step("CheckWarnings",-l," Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear"): button_press("OK"): } else { tl_step("CheckWarnings".-l," Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear"): }
192
Приложение В. Автоматизация приложения Pizza Order
CheckAEFormat cal1 "OpenPaymentPage"(); set_^wi ndow( "Pi zzaOrderi ngPage"): edit_set("name"."Ilya Vinnichenko"); list_select_item("CardType","American Express"); edit^set("numb"."1234567890123"); 1i st_se1ect^item("Month"."January"): 1 ist__selectJtem( "Year", "2007"); edit^setC"Address"."1600 Pennsylvania Avenue NW Washington. DC 20500 USA"): button_press("Submit"); if (win_^exists("WarningMsg".5)=E__0K) { set_window("WarningMsg"): if (obj_exists("{class: static_text. MSW^id: 65535, value: \" Incorrect Card Number. Valid format is 1234 567890 12345\"}")=E_0K) tl_step("CheckWarnings",0." Incorrect Card Number. Valid format is 1234 567890 12345 appeared") else tl_step("CheckWarning$".-l," Incorrect Card Number. Valid format is 1234 567890 12345 did not appear"): button_^press("OK"): } else { tl_step("CheckWarnings".-l," Incorrect Card Number. Valid format is 1234 567890 12345 did not appear"): }
SilkTest Библиотека функций (UDF.inc) INTEGER GetNumChar (STRING sTmp. STRING sChar) INTEGER c = l
while(StrPos(sTmp,sChar)!=0) sTmp = SubStrCsTmp, StrPosCsTmp. sChar)+l. Len(sTmp) - StrPosCsTmp, sChar)) C++
return с wind ass Html Table : Html Table BOOLEAN TableCheckData (string filename) HFILE OutputFileHandle ARRAY [3] OF STRING ExpectedData INTEGER i=l.c=l INTEGER HTMLColumnCount. HTMLRowCount STRING line
Структура автоматизации
193
STRING Tmp = "" TABLECELL CurCell BOOLEAN bResuU = TRUE list of string IsActualResult // Открыть файл для чтения: OutputFileHandle = FileOpenCfilename, FM_READ) // Провести выборку и определение данных: while(FileReadLine (OutputFileHandle. line)) if (ArraySize(ExpectedData)
// Закрыть файл: FileClose (OutputFileHandle) // Проверить, что количество строк в таблице соответствует ожидаемому: HTMLRowCount = this.GetRowCountO if ((HTMLRowCount+1) != ArraySize(ExpectedData)) LogErrorC'Data verification error") LogError("Expected number of rows: "+Str(ArraySize(ExpectedData))) LogError ("Actual number of rows: " + Str(HTMLRowCount+l)) bResult = FALSE // Проверить, что количество столбцов в таблице соответствует ожидаемому: HTMLColumnCount = this.GetColumnCount О if (HTMLColumnCount != GetNumChar (ExpectedData[l],"|")) LogError("Data verification error") LogError("Expected number of columns: "+Str(GetNumChar(ExpectedData[l]."|"))) LogError ("Actual number of columns: " + Str(HTMLColumnCount)) bResult = FALSE for(c=l;c<=HTMLColumnCount:C++) Tmp = Tmp + "I" + this.GetColumnName(c) if(ExpectedData [1]!= SubStr(Tmp,2)) LogError("Data verification error") LogError("Expected headers value: "+ExpectedData[i]) LogError ("Actual headers value: " + SubStr(Tmp,2)) bResult = FALSE // Построчно произвести сравнение возвращенных данных с ожидаемыми: for(i=l:i<=HTMLRowCount;i++) Tmp = "" IsActualResult = this.GetRowText(i) for(c=l;c<=HTMLColumnCount;C++) do Tmp = Tmp + "I" +lsActualResult[c] except Print("Row " + Str(i) +" has " + Str(c-l) +" columns") if(ExpectedData [i+l]!= SubStr(Tmp,2))
194
Приложение В. Автоматизация приложения Pizza Order
LogErrorC'Data v e r i f i c a t i o n error") LogError("Expected value: "+ExpectedData[i+l]) LogError ("Actual value: " + SubStr(Tfflp,2)) bResult = FALSE / / Вывести результаты сравнения: i f (!bResult) LogError("Test failed") return bResult wind ass CheckBox : CheckBox VOID IntCheck (integer iCheckFlag) i f (iCheckFlag = 1) this.CheckО i f (iCheckFlag = 0) this.UnCheckO appstate OpenOrderPageO i f ((PizzaOrderingPage.Exists()=FALSE) (CalculateOrder.Exists()=FALSE))
Browser. InvokeO Browser. CloseOthers О Browser.LoadPage("C:\Temp\index.html") appstate OpenPaymentPageO if ((PizzaOrderingPage.Exists()=FALSE) || (Submit.Exists()=FALSE)) Browser. InvokeO Browser. CloseOthers О Browser.LoadPage("C:\Temp\ calс.html") Библиотека объектов ( A p p G U I M a p . i n c )
window BrowserChild PizzaOrderingPage tag "Pizza Ordering Page" parent Browser Html Heading PizzaType tag "Pizza Type" Html Heading Toppings tag "Toppings" HtmlRadioList PizzaType [+] multitag "Pizza Type" HtmlCheckBox Pepperony [+] multitag "Pepperony ?$2.00?" HtmlCheckBox Mushrooms [+] multitag "Mushrooms ?$1.50?" "#2" HtmlCheckBox Meat
Структура автоматизации [+] multitag "Meat ?$2.50?" "#3" HtmlPushButton CalculateOrder [+] multitag "Calculate Order" "#1" HtmlPushButton Refresh [+3 multitag "Refresh" HtmlTable OrderSummary tag "Calculate Order" HtmlColumn Size tag "Size" HtmlColumn Toppings tag "Toppings" HtmlColumn Price tag "Price" Html Link Mail Link multitag "someone@somesite.com" "$mai1 to:someone@somesite.com[l]" Html Image ConfirmOrder [+] multitag "calc" "$fi1e:???J:?Books?Automati on?WebApp?calс.html' HtmlTextField Name multitag "Name:" "#1" HtmlTextField CardNumber multitag "Number:" "#2" HtmlPopupList CreditCardType multitag "Credit Card Type:" HtmlListBox Day multitag "Exp.Date" HtmlPopupList Month multitag "Number:" "#2" HtmlTextField Address multitag "Address" "#3" HtmlPushButton Submit multitag "Submit" window DialogBox WarningMsg tag "Microsoft Internet Explorer"
195
196
Приложение В. Автоматизация приложения Pizza Order
parent Browser PushButton OK multitag "OK" "$2" StaticText StaticText multitag "You did not specify name" "$65535" Библиотека скриптов (TestPlan.t) use ("UDF.inc") use ("AppGUIMap.inc") testcase SelectOptionsO appstate OpenOrderPage Integer i,c PizzaOrderingPage.SetActive() for(i=l;i<=3;i++) PizzaType.$elect("r+Str(i)) for(c=0;c<=6;c++) Meat.IntCheck((c=-l || c==4 || c=5)?l:0) Mushrooms.IntCheck((c=2 || c>=4)?l:0) Pepperony.IntCheck((c=3 || c==4 || c==6)?l:0) testcase CheckLinkO appstate OpenOrderPage PizzaOrderingPage.SetActiveO MailLink.ClickO # # Проверка почтового клиента (здесь не описывается, так как зависит от конфигурации системы) testcase CheckCalcO appstate OpenOrderPage Integer arrCount = 0 Boolean bResult LIST of STRING filename = {...} "C\TestData\Expectedl" "C\TestData\Expected2" "C\TestData\Expected3" "C\TestData\Expected4" "C\TestData\Expected5" "C\TestData\Expected6" "C\TestData\Expected7" "C\TestData\Expected8" "С\TestData\Expected9" "C\TestData\ExpectedlO" "C\TestData\Expectedll" "C\TestData\Expectedl2"
Структура автоматизации
197
"C\TestData\Expectedl3" "C\TestData\Expectedl4" "C\TestData\Expectedl5" "C\TestData\Expectedl6" "C\TestData\Expectedl7" "C\TestData\Expectedl8" "C\TestData\Expectedl9" "C\TestData\Expected20" "C\TestData\Expected21" Integer i,c Pi zzaOrderi ngPage.SetActi ve() for(i=l;i<=3;i-H-) Pi zzaType.Select("#"+Str(i)) for(c=0:c<=6;c-H-) Meat.IntCheck((c=l || c==4 || c=5)?l:0) Mushrooms.IntCheck((c=2 || c>=4)?l:0) Pepperony.IntCheck((c==3 || c = 4 || c==6)?l:0) CalculateOrder.ClickO bResult = SummaryTable. TableCheckDataC filename[arrCount]) Print ("CheckCalc status for {filename[arrCount]} is {bResult}") arrCount++ testcase CheckTypeClearO appstate OpenOrderPage Boolean bResult = TRUE PizzaOrderingPage.SetActive() PizzaType.Select("#l") Meat.CheckО Mushrooms.Check0 Pepperony.CheckO Refresh. CI ickO (PizzaType.GetSelIndex()==0)? bResult = TRUE : bResult = FALSE Meat.GetStateO? bResult = TRUE : bResult = FALSE Mushrooms.GetStateO? bResult = TRUE : bResult = FALSE Pepperony.GetStateO? bResult = TRUE : bResult = FALSE Print ("CheckTypeClear status is {bResult}") testcase GoToPaymentPageO appstate OpenOrderPage PizzaOrderingPage.SetActive() PizzaType.Sel ect("#l") Meat.CheckО Mushrooms. CheckO Pepperony.CheckO ConfirmOrder.ClickO if ((Pi zzaOrderi ngPage. Exists()=TRUE) || (Submit.Exists()=FALSE)) Print ("GoToPaymentPage FAILED.")
198
приложение В. Автоматизация приложения Pizza Order
testcase CheckWarnings appstate OpenPaymentPage PizzaOrderingPage.SetActive() Submit.ClickO i f (WarningMsg.StaticTextC'You did not specify name").Exists()=FALSE) Print ("You did not specify name message did not appear") i f (WarningMsg.StaticText("You did not specify Credit Card Number" ).Exists()—FALSE) Print ("You did not specify Credit Card Number message did not appear")
if (WarningMsg.StaticText("You did not specify Address"). Exi sts( )=FALSE) Print ("You did not specify Address message did not appear") testcase CheckCCExpired appstate OpenPaymentPage PizzaOrderingPage.SetActiveO Name.SetText("Ilya Vinnichenko") CardType.Select("Visa") CardNumber.SetText("1234567890123456") Month.Select("January") Year.Select("2004") Address.SetText("1600 Pennsylvania Avenue NW Washington. DC 20500 USA") Submit.ClickO i f (WarningMsg.StaticText("Incorrect Date. You card has expired") .Exi sts()=FALSE)
Print ("Incorrect Date. You card has expired did not appear") testcase CheckVisaFormat appstate OpenPaymentPage Pi zzaOrderi ngPage.SetActi ve() Name.SetText("Ilya Vinnichenko") CardType.Select("Visa") CardNumber.SetText("1234567890123") Month.Select("January") Year.Select("2007") Address.SetText("1600 Pennsylvania Avenue NW Washington. DC 20500 USA") Submit.ClickO i f (WarningMsg.StaticText("Incorrect Card Number. Valid format is 1234 5678 9012 3456").Exists()=-FALSE)
Print ("Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear") Pi zzaOrderi ngPage.SetActi ve() Refresh.ClickО Name.SetText("Ilya Vinnichenko") CardType.Select("MasterCard")
Структура автоматизации
199
CardNumber.SetText("1234567890123") Month.Select("January") Year.Select("2007") Address.SetText("1600 Pennsylvania Avenue NW Washington. DC 20500 USA") Submit.ClickO if (WarningMsg.StaticText("Incorrect Card Number. Valid format is 1234 5678 9012 3456").Exists()«FALSE) Print ("Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear") Pi zzaOrderi ngPage.SetActi ve() Refresh.ClickO Name.SetText("11ya Vinnichenko") CardType.Select("Discover") CardNumber.SetText("1234567890123") Month.Select("January") Year.Select("2007") Address.SetText("1600 Pennsylvania Avenue NW Washington. DC 20500 USA") Submit.ClickO if (WarningMsg.StaticText("Incorrect Card Number. Valid format is 1234 5678 9012 3456").Exists()==FALSE) Print ("Incorrect Card Number. Valid format is 1234 5678 9012 3456 did not appear") testcase CheckAEFormat appstate OpenPaymentPage Pi zzaOrderi ngPage.SetActi ve() Name.SetText("11ya Vi nni chenko") CardType.Select("American Express") CardNumber.SetText("1234567890123") Month.Select("January") Year.Select("2007") Address.SetText("1600 Pennsylvania Avenue NW Washington. DC 20500 USA") Submit.ClickO if (WarningMsg.StaticText("Incorrect Card Number. Valid format is 1234 567890 12345").Exists()=FALSE) Print ("Incorrect Card Number. Valid format is 1234 567890 12345 did not appear")
Алфавитный указатель
в blackbox testing, 18 BRD, Business Requirement Document, 16
Rational Robot, 35 regression testing, 19
s
F
script library, 24
FDD, Functional Design Document, 16 function library, 24
T
G graybox testing, 19 GUI-файл, 29
TDD, Technical Design Document, 16 TSL, Test Scripting Language, 38
и 0 object repository, 24
UDF, User Defined Functions, 148
w Q QA, 18
whitebox testing, 18
201
Алфавитный указатель
м активирование окна, 74
библиотека объектов, 24 скриптов, 24 функций, 24
в вспомогательные функции, 107 имитации действий, выполняемых мышью, 111 имитации клавиатурного ввода, 107 оповещения о результатах, 120 проверки существования объекта, 124 работы с системой, 117 работы с файлами, 126 синхронизатинт, 122
и
массив данных, 43 массивы, 44
н нестарщартные классы, 164
обработчик событий, 143 окно активирование, 74 операторы, 46 4test, 46 SQABasic, 47 TSL, 46 сравнения, 48 4test, 48 SQABasic, 48 TSL, 48 условные, 49 4test, 51 SQABasic, 52 TSL, 49 цикла, 53
имя функции, 148 инженер по качеству, 16 инфраструктура, 24
n
к
переменные, 38 перепроверочное тестирование, 19
компилируемые модули, 28 константа, 40
Л логические операторы, 47 4test, 47 SQABasic, 48 TSL, 47
скрипт, 25 скрипты в WinRunner, 28 средство опознавания объектов, 27 GUI Spy, 31 Inspector, 37 Window Identifiers, 34
202
тестирование с закрытым кодом, 19 с открытым кодом, 18 с полуоткрытым кодом, 19 тестировщик, 16 тест-кейс, 21
функции приведения типов, 56 работы с базами данных. 133
Алфавитный указатель
функции {продолжение) работы с массивами, 59 работы со строками, 64 функции пользователя, 148 функциональность Record/Playback, 26
язык скриптов, 38 4test, 38,41 SQABasic, 38,42 TSL, 38,39
Илья Викторович Винниченко
Автоматизация процессов тестирования Главный редактор Заведующий редакцией Руководитель проекта Литературный редактор Художник Корректоры Верстка
Е. Строганова А. Кривцов Ю. Суркис Н. Рощииа Л. Адуевская Н. Цыбульникова, Н. Шелковникова Ю. Сергиеико
Лицензия ИД № 05784 от 07,09.01. ООО «Питер Принг», 194044, Санкг-Пстербург, пр. Б. Сампсониевский, 29а. Налоговая льгота — общероссийский классификатор продукции ОК 005-93, том 2; 95 3005 — литература учебная. Подписано в печать 21.02.05, Формат 6 0 x 9 0 / 1 6 . Усл. п. л. 11. Тираж 3000. Заказ № 1478. Отпечатано с готовых диапозитивов в ООО «Типография Правда 1906». 195299, С.-Петербург, Киришская ул., 2.