Descriptive Programming в QuickTest Pro

    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. спасибо за карму, перенес в «Тестирование».

    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 2

      0
      Когда то тестировал на Rational Robot, там была функция сравнения периодичных результатов тестирования (методом попиксельного сравнения).
      Интересно, присутствует ли в Descriptive Programming такой функционал?
        0
        Попиксельное сравнение в QTP есть, но это последний способ сравнения, который стоит применять. Удобнее и надежнее вытащить проверяемую информацию непосредственно из контролов.

        DP — это не инструмент автоматизации, а техника обращения объектов в инструменте QTP.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое