Pull to refresh

Descriptive Programming в QuickTest Pro

IT systems testing
QuickTest Professional – популярный инструмент для автоматизации функционального тестирования. В немалой степени его популярность обусловлена наличием в нем рекордера пользовательской активности, который позволяет записать действия пользователя и преобразовать их в скрипт.
Объекты, с которыми взаимодействует пользователь, автоматически идентифицируются QTP и сохраняются в специальное хранилище – репозиторий. При сохранении в репозиторий, QTP автоматически сохраняет идентификационные свойства объекта, но делает это не всегда правильно. Например, если на веб-странице присутствуют несколько таблиц (даже если у каждой из них есть свой ID), QTP идентифицирует их по порядковым номерам. Такой способ идентификации объектов вызывает проблемы при проигрывании автотестов. Более того, многие объекты вообще не попадают в репозиторий при записи. Это вызвано многими причинами, наиболее частыми из которых является сложная верстка или верстка с применением DIV-ов. Однако, существует способ обращаться к объектам тестируемого приложения на этапе выполнения скрипта, минуя обращение к репозиторию.
Этот способ называется Descriptive Programming (DP).


Основной идеей DP является поиск и обращение объектов по их идентификационным свойствам. Для DOM-элементов это может быть ID, Name, Тег, Inner Text и т.д. Например, для обращения к кнопке с Id равным SubmitBtn нужно использовать следущую конструкцию:

WebButton("html tag:=button","html id:=SubmitBtn")

* This source code was highlighted with Source Code Highlighter.


Обращения к объектам QTP иерархические. Можно комбинировать обращение к репозиторию и DP, но с одним ограничением – если на каком-то уровне иерархии использовался DP, то на следующих уровнях иерархии нельзя обращаться к репозиторию. Например:
Browser("Browser").Page("Page").WebElement("table1").WebElement("html tag:=table","html id:=tbl_grid") 'верно

Browser("Browser").Page("Page").WebElement("html id:=table1").WebElement("tbl_grid") 'неверно


* This source code was highlighted with Source Code Highlighter.


Все поисковые конструкции в DP являются регулярными выражениями.

Browser("Browser").Page("Page").Link("inner text:=Subject[\d]{1,2}") 'найти ссылку, inner text которой содержит Subject, и от одной до двух цифр.


* This source code was highlighted with Source Code Highlighter.


Теперь давайте поиграем ;).
Нам понадобится QTP, 14-ти дневную пробную версию можно взять здесь (требуется HP Passport, регистрация бесплатна).

В качестве объекта автоматизации снова выберем Калькулятор
1. Запускаем QTP.
2. Создаем новый тест
3. Нажимаем кнопку «Record».
4. В появившемся окне переходим на вкладку Windows Application, нажимаем в ней «+» и вводим calc.exe в поле ввода Application


5. Нажимаем ОК.
6. В автоматически запущенном калькуляторе нажимаем кнопки 1,2,*,5,=
7. В окне результата видим 60
8. Нажимаем Ctrl+F12 для создания Выходного значения теста.
9. В появившемся окне ставим галочку напротив свойства text, по умолчанию значение сохраняется в ячейку таблицы данных. Нажимаем ОК


10. Закрываем Калькулятор
11. Нажимаем Stop record в QTP

Что же у нас получилось в результате? На вкладке Expert View – наш скрипт
Window("Calculator").WinButton("1").Click
Window("Calculator").WinButton("2").Click
Window("Calculator").WinButton("*").Click
Window("Calculator").WinButton("5").Click
Window("Calculator").WinButton("=").Click
Window("Calculator").WinEdit("Edit").Output CheckPoint("Edit")
Window("Calculator").Close

* This source code was highlighted with Source Code Highlighter.


Для одного тестового сценария – отлично. Но если нам нужно проверить не только умножение, а и деление, сложение. А еще существуют отрицательные числа… Вариант в лоб – записывать для каждого кейса свой Action, имеет существенный недостаток – трудно поддерживать. Вариант получше – добавить в репозиторий все кнопки калькулятора и нажимать на них программно.
A = "1"

Window("Calculator").WinButton(A).Click

* This source code was highlighted with Source Code Highlighter.


Вариант неплох, но его очень трудно поддерживать – в случае добавления или удаления кнопок нужно изменять репозиторий объектов.

И здесь нам на помощь придет DP – у каждой кнопки есть надпись, значит можно идентифицировать кнопку по ней.
Window("Calculator").WinButton("text:=2").Click

* This source code was highlighted with Source Code Highlighter.


И в этом случае мы сможем написать универсальную процедуру для нажатия на кнопку. Более того, мы сможем сделать унифицированный action для проверки вычислений калькулятора.

Создадим новый Action – Insert->Call to new Action. Зададим ей имя Calc_Tests и снимем галочку Reusable Action. Передвинем Calc_Tests в окне Test Flow выше Action1.
Далее нам нужно добавить параметры к тому Action, который был у нас изначально, по умолчанию Action1. В окне TestFlow нажимаем на него правой кнопкой->Action properties->Parameters. Добавляем входные строковые параметры OperList и Expected и выходной строковый параметр ActualResult.
Изменяем исходный код Action1 следующим образом:
operList = Parameter("OperList") ' получить входной параметр OperList<br>expectedRes = Parameter("Expected") ' получить входной параметр Expected<br><br>operArr = split(operList,";") ' разбить строку в массив по разделителю ;<br><br>For each oper in operArr ' для каждого элемента массива<br> Button_Click Window("Calculator"), oper ' нажать на заданную кнопку<br>Next<br><br>actual = rtrim(Window("Calculator").WinEdit("Edit").GetROProperty("text")) 'получить текущее значение результата<br><br>If actual <> expectedRes Then<br> reporter.ReportEvent micFail, "Calc Test","Expected: " & expectedRes & " <> Actual: " & actual ' запротоколировать результат<br>else <br> reporter.ReportEvent micPass, "Calc Test","Expected: " & expectedRes & " = Actual: " & actual<br>End If<br><br><br>Button_click Window("Calculator"), "C" ' сброс калькулятора<br>Button_click Window("Calculator"), "MC" ' и памяти<br><br>Parameter("ActualResult") = actual ' возврат актуального результата операции<br><br>' процедура нажатия на кнопку, идентифицированную по по ее свойству text<br>Sub Button_click(Obj,btn_label) <br> If Obj.WinButton("text:="& btn_label).Exist then ' если кнопка существует <br> Obj.WinButton("text:="& btn_label).Click ' нажать ее<br> end if<br>End Sub<br><br><br>* This source code was highlighted with Source Code Highlighter.

Переходим в Calc_Tests и вставляем вызов Action1: Insert->Call to Existing Action–>Action1
Изменяем строку вызова Action1 на
RunAction "Action1", oneIteration, "1;2;\*;5;=","60,",actual

* This source code was highlighted with Source Code Highlighter.

Символ * экранирован, потому что он является специальным символом регулярного выражения, а как написано выше: все выражения DP – регулярные выражения.

Можно добавить еще один кейс для проверки. Код Calc_tests может выглядеть так:

Dim actual<br>RunAction "Action1", oneIteration, "1;2;\*;5;=","60,",actual<br> ' экранирование * нужно потому, <br> 'что * является специальным символом в регулярных выражениях.<br>RunAction "Action1", oneIteration, "2;2;\+;5;=","27,",actual ' то же самое для +<br>Window("text:=Calculator").Close<br>ExitTest<br><br>* This source code was highlighted with Source Code Highlighter.


Если запустить тест, то калькулятор проведет два вычисления и автотест сравнит ожидаемые и полученные результаты. В результате выполнения мы должны получить отчет о выполнении с «зелеными галочками» ;)

Descriptive programming помогает решать задачи, которые в традиционном подходе или нерешаемы, или очень трудоемки.

P.S. всех причастных с праздником – днем Тестировщика.

P.P.S. спасибо за карму, перенес в «Тестирование».

Tags:автоматизация тестированиятестированиеquick test professional
Hubs: IT systems testing
Total votes 6: ↑5 and ↓1 +4
Views5.6K

Popular right now

Top of the last 24 hours