Введение в автоматизированное тестирование с использованием Mercury QuickTest Pro в вопросах и ответах |
02.10.2008 13:58 |
Автор: Михаил Давыдов, Luxoft Company (www.luxoft.com) В материале рассматриваются вопросы, которые чаще всего возникают при первом знакомстве с инструментом автоматизации функционального и регрессионного тестирования Mercury Interactive — QuickTest Pro. В статье обсуждается работа с тремя версиями QTP — 6.5, 8.2 и 9.0. Если это не оговаривается специально, ответы на вопросы подходят для всех трёх версий.
Краткая аннотация:В этой статье я попробую ответить на вопросы, которые чаще всего возникают при первом знакомстве с инструментом автоматизации функционального и регрессионного тестирования Mercury Interactive — QuickTest Pro. В статье обсуждается работа с тремя версиями QTP — 6.5, 8.2 и 9.0. Если это не оговаривается специально, ответы на вопросы подходят для всех трёх версий. Отмечу впрочем, что почти все вопросы, рассматриваемые в статье, освещены в Help, a многие ответы ранее уже публиковались на форуме проекта Software-Testing.Ru Actions, IterationsВопрос: Что такое Action? Использования объекта DataTable и параметризацияВопрос: Что такое Data-driven тестирование? Как параметризировать тест? ЛоггингВопрос: Что записывается в лог QTP, и можно ли это настроить? Распознавание объектов в QTPВопрос: При воспроизведении записанного теста, QTP не распознаёт объекты. Почему? Что делать? Работа с Object RepositoryВопрос: Объекты типа Page/Frame дублируются в Object Repository при записи скрипта. Почему? Методы Test ObjectВопрос: Как получить доступ к дочерним объектам (если мы не знаем их свойств)? СинхронизацияВопрос: Тест не дожидается появления/отрисовки объекта, сообщает об ошибке и переходит к выполнению следующих операторов (также с ошибками). Как сделать так, чтобы QTP дожидался появления объектов либо их определённого состояния (например, enabled)? Свойства ОбъектовВопрос: Чем отличаются TO Property, RO Property и Run-time object property? Работа с библиотеками и программирование на VBScriptВопрос: Что такое библиотека функций? Как подключить библиотеку? Использование объекта EnvironmentВопрос: Зачем нужен объект Environment? Запуск пакетов тестов и использования QTP Automation Object ModelВопрос: Как запустить тест/набор тестов из командной строки? Undocumented featuresВопрос: Можно ли использовать HTML в логах? Actions, IterationsВопрос: Что такое Action?Ответ: Action — это независимый скрипт в составе теста. Он имеет свой контекст имен переменных, свой локальный Object Repository (хранилище описаний объектов пользовательского интерфейса тестируемого приложения), свой Action Sheet (называемый, также Local Sheet — таблица для хранения значений параметров; его можно вызывать из других тестов. Кроме того, начиная с QTP 8.0 у Actions есть свои параметры (не путать с Data Table parameters: в данном случае имеются в виду значения переменных, передающихся в action извне, либо выходные параметры, аналогично параметрам функций). В свойствах Action можно указать, сколько раз подряд его надо запустить (количество итераций) — это имеет смысл делать при активном использовании параметризации. При использовании параметризации, при каждой следующей итерации Action, все локальные параметры принимают новое значение — значение из ряда Action Sheet, совпадающего с номером итерации. Следует иметь в виду, что кроме Action Sheet, существует Global Sheet (один на весь тест) — значения параметров, описанные в нём, изменяются при переходе к следующей итерации теста, а не Action. В Mercury считают, что один Action должен примерно соответствовать одной бизнес операции, или одному Use Case. То есть, использование Actions (по Mercury) — основной способ функциональной декомпозиции. В реальности, вместо Actions для этих целей часто бывает удобнее использовать функции. Впрочем, это зависит от стиля Ваших тестов, в частности, от того, используете ли Вы параметризацию. Вопрос: Что такое Reusable Action?Ответ: Для вызова Action из другого теста (либо из другого Action) необходимо, чтобы в свойствах action (Action Properties) была выставлена галочка "Reusable action". Вопрос: Какие есть способы передачи значений переменных между разными Actions?Ответ: Каждый Action имеет свой контекст имён, поэтому переменные одного Action не видны из другого. Универсальный способ передачи переменных, начиная с версии QTP 6.0 — использование объекта Environment. Кроме того, начиная с версии 8.0 у Actions появились параметры (см. Help: Action properties, Action call properties, Action parameters). То есть, Action, — это в некотором смысле аналог функции с входными и выходными параметрами. Использование объекта DataTable и параметризацияВопрос: Что такое Data-driven тестирование? Как параметризировать тест?Ответ: Для того, чтобы вместо фиксированных значений параметров функций (например, текста, вводимого в поле ввода) использовать (в цикле) значения из таблицы, используется подход, называемый Data-Driven тестирование. При параметризации, исполнение теста происходит в форме исполнения двух вложенных циклов — по всему тесту целиком и по отдельным Actions. Соответственно, есть 2 типа параметров: глобальные — для всего теста, и локальные — для отдельных Actions. В начале каждой итерации все параметры приобретают значения, хранящиеся в строчке соответствующей таблицы (Global Sheet/Action Sheet), номер которой равен номеру итерации (теста или Action соответственно). Вопрос: Что такое Run-time data sheet?Ответ: Кроме использования Data Table для хранения входных тестовых данных (параметры), QTP позволяет использовать его для хранения выходных данных (Output Values). Во время выполнения теста, значения в Data Table можно менять, однако они не будут сохранены в тесте. Зато их можно будет увидеть в отчёте об исполнении теста (логе). Вопрос: Как приступить к параметризации, с чего начать?Ответ: Два самых удобных способа:
Оба способа годятся только при параметризации методов тестовых объектов в тесте. В библиотеках параметризация по понятной причине не доступна. Вручную это делается так: 1. В соответствующей таблице (Local Sheet или Global Sheet): DataTable("myParam",dtGlobalSheet) — для глобальных параметров (параметров теста)
Вопрос: Какие существуют ограничения на использование DataTable?Ответ: Во время исполнения нельзя добавлять дополнительные ряды в таблицу. Кроме того, использование большого количество параметров и/или рядов заметно влияет на производительность. Поэтому DataTable рекомендуется использовать только по прямому назначению — для параметризации и хранения Output Values (Хотя существует развитый API для работы с таблицами — cм. Help по объектам: DataTable, Sheet, Parameter). ЛоггингВопрос: Что записывается в лог QTP, и можно ли это настроить?Ответ: Записываются все действия над тестовыми объектами (то есть, все statements, полученные во время записи теста) и сообщения об ошибках. Flow Controls statements, вызовы пользовательских функций и т.п. не записываются. Это — то, что QTP пишет в лог, если запись в лог не контролировать программно. Для работы с логом служит встроенный объект Reporter. У него есть всего один метод — ReportEvent() и одно свойство — Filter. Для записи в лог своего собственного сообщения (например, комментария или сообщения об ошибке), используется метод ReportEvent(). Метод хорошо описан в Help. При просмотре лога можно отфильтровать события по статусу (Done — информационные сообщения, Passed — успешно пройденные шаги; Warning, Failed — ошибки выполнения теста). Кроме того, записываемыми в лог сообщениями можно управлять из теста с помощью свойства Filter. При значении 0 (по умолчанию), записываются все сообщения; при 1 — Warning и Failed, 2 — failed, 3 — ничего. Причём, не записанные в лог сообщения НЕ влияют на статус теста и статистику. Существует один хитрый трюк, позволяющий использовать в тексте сообщений лога HTML — см."Undocumented features". Распознавание объектов в QTPВопрос : При воспроизведении записанного теста, QTP не распознаёт объекты. Почему? Что делать?Ответ: При записи теста QTP записывает описания объектов интерфейса тестируемого приложения (Application Under Test, AUT), с которыми тест взаимодействует, в Object Repository. Если QTP что-то не распознаёт, с 99.9% вероятности это означает, что свойства распознавания в Object Repоsitory указаны неверно. Это происходит потому, что при записи QTP записывает в Object Repository совершенно определённый набор свойств объекта, одинаковый для каждого отдельного типа объектов. Какие именно свойства QTP записывает для каждого типа объектов определяется настройками Object Idenfication (Tools>Object Identification...). Следует:
Уже записанные скрипты использовать после такой процедуры не рекомендую. Можно, конечно, вручную поменять свойства распознавания для каждого объекта в Object Repository, но это может привести к неприятным последствиям — см. Раздел "Работа с Object Repository" Вопрос: Как правильно настроить распознавание объектов в QTP с помощью настроек Object Identification?Ответ: В настройках Object Identification от обилия опций глаза разбегаются. Однако, всё довольно просто: Рис.1. Окно Object Identification Mandatory Properties — свойства, которые QTP прописывает для этого типа объектов в Object Repository ВСЕГДА. Assistive Properties — свойства, которые QTP прописывает в Object Repository ТОЛЬКО если во время записи объекта в OR в приложении наличествуют более одного объекта, удовлетворяющих Mandatory Properties Ordinal Identifier — QTP использует, если даже при использовании и Mandatory и Assistive Propertires им удовлетворяет более одного объекта. Ordinal Identifier определённым образом "нумерует" похожие объекты. Делает он это так:
Соответственно, в качестве Mandatory свойств надо прописывать такие свойства, которые чаще всего остаются неизменными от версии к версии, но при этом позволяют отличить один объект от другого. Assistive свойства выбирают так: это свойства которые наверняка позволят отличить объекты один от другого, но есть небольшая вероятность их изменения от одной версии приложения к другой. Настройка Objеct Identification зависит от манеры программирования разработчиков, специфики используемых технологий и т.д. Настройки QTP по умолчанию не слишком удачны для работы с Win32 GUI приложениями, написанными НЕ на MFC и для динамических страниц Web. Наибольшие проблемы возникают от следующих настроек: — Standard Windows: Практически для всех типов объектов в качестве Assistive свойства указано window id. Для приложений, написанных без использования Microsoft Fundation Classes это приводит к тому, что объекты не распознаются при воспроизведении, так как window id меняется от сессии к сессии. — Web: Browser — не выставлены Mandatory и Assistive свойства. В качестве Ordinal Identifier используется Creation time. В результате, надёжность воспроизведения зависит от числа открытых браузеров и порядка их создания. Я использую в качестве Mandatory свойства — title. Настройка Object Identification очень сильно зависит от специфики тестируемого Web-приложения, и какие-то общие рекомендации дать сложно. Рекомендуется с помощью Object Spy выяснить, по каким свойствам легче всего идентифицировать тот или иной тип элемента интерфейса (см. ответ на предыдущий вопрос). Вопрос: Что такое Smart Identification?Ответ: Это такая опция, которую лучше не использовать :) Если серьёзно, то Smart Identification это опция, которая призвана сгладить неумелую настройку пользователем свойств распознавания объектов — с её помощью находятся объекты, которые не удовлетворяют их описанию в Object Repository. Проблема же заключается в том, что эту опцию правильно настроить заметно сложнее чем Object Identification - в результате, её использование у начинающих тестировщиков приводит к тому, что QTP пытается работать не с теми объектами (замечу, что это заметно хуже того случая, когда QTP просто не находит объекта). Опытные же пользователи QTP этой опцией предпочитают не пользоваться — так как умеют настраивать Identification так, что если QTP не находит объекта — значит его нет :) Интересующихся отсылаю к Help — статья "Smart Identification, configuring" Вопрос: Можно ли распознавать объекты интерфейса без использования Object Repository?Ответ: Можно. Причём, двумя разными способами: 1. C использованием объекта Description: Пример из Help ("Using Description Objects for Programmatic Descriptions") : set EditDesc = Description.Create() 2. Явно указывая свойства распознавания: Синтаксис: TestObject("PropertyName1:=ProperyValue1", "..." , "PropertyNameX:=ProperyValueX") Пример из Help ("Entering Programmatic Description Directly into Test Statements"): Set MyWin = Window("Text:=Myfile.txt - Notepad") Вопрос: Что делать, если элемент интерфейса тестируемого приложения распознаётся как "WinObject", несмотря на то, что является более специализированным элементом (таким как кнопка, drop-down list, edit box, и т.п.)?Ответ: Необходимо настроить распознавание для этого объекта (точнее, для всех объектов с тем же значением свойства native class). Для этого Вызываем диалог Object Identification: Tools->Object Identification: Рис.2а: Настройка распознавания объектов нестандартных классов — последовательность действий.
Работа с Object RepositoryВопрос: Объекты типа Page/Frame дублируются в Object Repository при записи скрипта. Почему?Ответ: Действительно, по умолчанию QTP создаёт новые объект после каждого запроса "POST" на сервер. Чтобы этого не происходило в 6.5: Tools>Options>Закладка "Web" >Кнопка "Advanced": Рис.3а: Настройка свойств записи Page/Frame в версии QTP 6.5 Create New Page object for: Установите "Pages with different test object description". Optimize Page/Frame test object creation - снимите флажок.
В QTP 8.2 и 9 эти опции вынесены в отдельный диалог: Рис.3б: Настройка свойств записи Page/Frame начиная с версии 8.2 Вопрос: В каких случаях QTP создаёт новые объекты в Object Repository (настройка Web settings?)Ответ: QTP будет создавать новые объекты в Object Repository если :
Поэтому, СНАЧАЛА выставляем Object Identification Settings, потом записываем скрипт. При изменении Object Identification Settings, с большой долей вероятности в репозитории будут создаваться новые объекты. Вопрос: Чем отличается тип репозитория Shared от per Action?Ответ (для QTP версий ниже 9.0): По умолчанию, QTP создает свой Object Repository для каждого Action. Такие репозитории штатными средствами не переносятся из одного Action в другой, не могут быть "слиты" и т.п. Каждый Action может использовать только свой репозиторий. Кроме "Per-Action" режима работы с OR, существует режим "Shared". Внимание, выбрать режим Object Repository для теста можно только ДО начала его записи. Для этого идём в Test Settings>Resources, и выставляем опцию "Shared". Рис 4: Выбор типа репозитория для теста в QTP 6.5 — 8.2 Теперь:
Ответ (для QTP 9.0): Начиная с версии 9, в QTP каждый тест может иметь одновременно локальные (для каждого Action'a) и разделяемые (для нескольких тестов) репозитории. Причём, каждый отдельный action может ссылаться одновременно более чем на один shared репозиторий (для каждого action’a репозитории могут быть разные). Как это выглядит? Для того, чтобы проассоциировать каждый action со своим репозиторием надо открыть диалог "Associate Repositories" (Resources>Associate Repositories..): Рис.5: Окно Associated Repositories в QTP 9.0 Теперь при открытии диалога Object Repository показывается не отдельный репозиторий, а "сумма" проассоциированных с текущим action shared репозториев и локального репозитория Action'a. Конфликты репозиториев разрешаются автоматически — учитывается порядок следования shared репозиториев в списке в диалоге "Action Properties", закладка "Associated Repositories". В окне Object Repository редактировать можно ТОЛЬКО объекты, лежащие в локальном репозитории. Чтобы редактировать shared репозиторий, его необходимо открыть в окне "Object Repositories Manager" (Resources>Object Repository Manager). Причём, не забудьте при открытии убрать опцию "Open as read-only". Object Repository Manager позволяет сливать локальные и shared репозитории, сливать разные shared репозитории с помощью Object Repository Merge Tool, перемещать объекты между репозиториями, и т.п. Возникает закономерный вопрос: как использовать все эти новые возможности (и зачем они вообще нужны)? Ответ довольно прост — для обеспечения комфортной совместной работы над тестами, использующими один и тот же Shared Object Repository. То есть, пока мы пишем/редактируем наш отдельно взятый тест, мы не меняем объектов в Shared Object Repository. Когда все тесты готовы и отлажены, их Object Respositories сливаются с shared. Вот, собственно и всё (до следующего релиза ;-) ). Ну а новые возможности, такие как использование нескольких репозиториев одновременно, использование различных репозиториев для разных action'ов, экспорт и импорт в XML, я думаю, лишними не будут. Вопрос: Каким образом свойства распознавания объектов в OR могут поменяться?Ответ: Не забывайте при запуске теста в режиме Update Mode снимать галочку "Update test object properties" — иначе все описание всех объектов, с которыми работает тест будут обновлены, причём свойства, отсутствующие в Object Identification Settings для данного типа объектов будут удалены. Вопрос: Можно ли отказаться от использования Object Repository? Как?Ответ: Да, многие тестировщики, работающие с QTP стремятся отказаться от работы с Object Repository. Причин много (правда, многие из них устранены с выходом QTP 9.0). Среди причин отказа от использования Object Repository можно перечислить:
Основной плюс репозитория, в том что это способ повторного использования данных, который позволяет один раз в одном месте изменить описание объекта, который многократно используется тестом. Кроме того, отказавшись от использования репозитория мы автоматически отказываемся от использования записи скриптов. Встаёт вопрос — как отказаться от OR и при этом не лишится этих преимуществ? К сожалению, ни одно решение не позволяет научить QTP записывать тест без использования Object Repository. Другая проблема — повторное использование определений объектов решается с переменным успехом. Многие пытаются создавать свои альтернативные OR — на XML, в Excel и т.п. Однако, я не вижу больших преимуществ такого решения по сравнению со стандартным Object Repository. Точнее, преимущества есть, но они скрадываются неудобством использования (главным образом — громоздкостью синтаксиса вызова объектов при их использовании либо (при простоте синтаксиса) — отсутствие решения проблем пересечения пространств имён (действительно, неприятно если для всех объектов придется придумывать разные имена вне зависимости от того, к какому объекту верхнего уровня они относятся)). Мне больше по душе подход, комбинирующий использование объектов Description (для дочерних объектов) с "Helper Functions", возвращающими объекты верхнего уровня, такие как Page, Frame, Window и т.п.: '== Функция для библиотеки - переводит строку в объект Description public function TODescriptionFromString(aString) set aDescription = description.create set TODescriptionFromString = aDescription 'Oпределяем Description для кнопки
set MyFrame_SearchBtn = TODescriptionFromString("innertext=Search;index=0")
'Helper для Frame'a 'Вполне компактная запись получается: Методы Test ObjectВопрос: Как получить доступ к дочерним объектам (если мы не знаем их свойств)?Ответ: Для этого есть замечательный метод — ChildObjects. Использовать ChildObject легко, и этот метод достаточно хорошо описан в Help. Set oDesc = Description.Create() В Web, метод ChildObjects применим к объектам типа Page и Frame. Другой способ — использовать Ordinal Identifier в качестве единственного свойства в описании. Тогда пример из Help будет выглядеть примерно так (не слишком изящно, скажем прямо, и, к тому же, заметно медленнее): Dim listsArr() Redim Preserve listsArr(i-1) for i = 0 to UBound(listsArr) При работе с объектом WebTable используется другой метод — ChildItem (см. Help). К сожалению, как этот, так и другие методы WebTable для работы с ячейками (например, GetCellData) работают чрезвычайно медленно с большими таблицами. В этом случае единственным решением является использование свойства .object таблицы. Вопрос: Что такое свойство object?Ответ: Свойство object есть почти у всех объектов Web (исключением является Browser), объектов VisualBasic, .NET , Java, ActiveX (при установке соответствующих Add-ins). С его помощью можно получить доступ к "родным" (native) свойствам и методам объекта соответствующей среды разработки. Так, свойство object Web-объектов предоставляет доступ к COM-объектам библиотеки MSHTML 4. Те кто знакомы с программированием DHTML страниц, поймут о чём я говорю — получив доступ к объекту элемента DOM мы с ним работаем так же, как если бы мы программировали DHTML cкрипт для Internet Explorer. Ниже приведён пример работы c полем .object WebTable: 'Эта функция позволяет получить текст ячеек таблицы в виде массива Public Function tableSaveToArray2D (table,Byref arr) If Not isObject(Table) Then If Not table.exist(10) Then set oTable = table.Object Redim Arr(rowcount-1,colcount-1) TableSaveToArray2D = true СинхронизацияВопрос: Тест не дожидается появления/отрисовки объекта, сообщает об ошибке и переходит к выполнению следующих операторов (также с ошибками). Как сделать так, чтобы QTP дожидался появления объектов либо их определённого состояния (например, enabled)?Ответ: Этот вопрос хорошо освещён в Help. Cм. "Adding Exist and Wait Statements"," Solving Synchronization Problems", " Modifying Timeout Values". Вкратце же: 1. Необходимо настраивать установки таймаутов: 2. Если надо дождаться появления объекта, надо использовать метод .Exist Синтаксис такой: .Exist(timeout) — ждать появления объекта timeout секунд. Возвращает true если удалось дождаться появления объекта, false — если нет. Используем так: var = TestObject.Exist(timeout) либо if not TestObject(timeout) then К сожалению, запись TestObject.Exist timeout не работает, видимо из-за нюансов определения этого метода. 3. Чтобы дождаться нахождения объекта в нужном нам состоянии, используем метод .WaitProperty: Пример #1 If Browser("index").Page("index").WebEdit("Account").WaitProperty("disabled", 0) Пример№2 If Browser("index").Page("index").Link("All kind of").WaitProperty("attribute/readyState", "complete", 4000) then
Browser("index").Page("index").Link("All kind of").Click
End If
Свойства ОбъектовК сожалению, терминология свойств объектов QTP не слишком прозрачна. Поэтому часто возникает путаница. Вопрос: Чем отличаются TO Property, RO Property и Run-time object property?Ответ: TO Properties — свойства объекта, используемые при его идентификации. Метод GetTOProperty возвращает то значение свойства, которое использовалось при его (объекта) идентификации. Если оно не использовалось, то ничего хорошего не возвращается. Список свойств объекта, которые можно использовать при идентификации указан в Help для каждого класса объектов. TO свойства показываются в Object Spy при выборе опции "Test Object Properties/Methods". Следует обратить внимание на то, что показываются ТОЛЬКО те свойства, которые прописаны в Object Identification, что весьма неудобно. RO Properties — свойства объектов, в данный момент отображаемых в тестируемом приложении. Их список — тот же, что и у TO Properties. Соответственно, метод GetROProperty возвращает свойства объекта в тестируемом приложении, только если объект этот в данный момент существует (не обязательно отображается). Run-Time Object properties — поля объекта .object. При тестировании Web есть трюк, позволяющий получить доступ к этим полям при использовании метода GetROProperty и при идентификации. Для этого используется конструкция attrubute/… Например, вот так: readyState = Browser("index").Page("index").GetROProperty("attribute/readyState")/ Но проще всё же записать так: readyState = Browser("index").Page("index").object.readyState Работа с библиотеками и программирование на VBScriptВопрос: Что такое библиотека функций? Как подключить библиотеку?Ответ: Библиотека функций содержит программный код, который загружается и исполняется до начала выполнения теста в отдельном контексте. Из этого следует что:
Библиотеки можно подключить на закладке Resources диалога Test Settings (Test>Settings..): Подключение библиотек При подключении библиотек обратите внимание на то, что:
Вопрос: В чём отличие подключения библиотеки в разделе Test Settings>Resources от использования функции ExecuteFile()Ответ: Текст библиотеки, загруженной с использованием ExecuteFile() (см. Help) не доступен при отладке, более того, использование ExecuteFile() приводит к сбою маркера текущей строки при отладке. Кроме этого, ExecuteFile загружает библиотеку в глобальный контекст имён. Поэтому модификаторы доступа, такие как private могут работать некорректно. Вопрос: Как использовать классы в библиотеках?Ответ: Единственная проблема с классами — то что экземпляры классов (то есть, объекты) с помощью оператора New можно создавать только в той же библиотеке, где определён класс (кроме случая загрузки библиотек функцией ExecuteFile()). Поэтому, для создания экземпляра класса из теста или другой библиотеки, необходимо в библиотеке, где определён класс, создать функцию-конструктор. Вот так: Class MyClass Function getMyClass() Вопрос: Как использовать функции, определенные в DLL?Ответ: Объявить с помощью метода Declare объекта Extern (cм. подробности в Help), после чего процедура либо функция становится методом объекта Extern (пример из Help): 'Declare FindWindow method
Extern.Declare micHwnd, "FindWindow", "user32.dll", "FindWindowA", micString, micString
'Declare SetWindowText method
Extern.Declare micLong, "SetWindowText", "user32.dll", "SetWindowTextA", micHwnd, micString
'Get HWND of the Notepad window
hwnd = Extern.FindWindow("Notepad", vbNullString)
if hwnd = 0 then
MsgBox "Notepad window not found"
end if
'Change the title of the notepad window
res = Extern.SetWindowText(hwnd, "kuku")
Вопрос: Как работать с объектами COM/ActiveX?Ответ: Создавать экземпляры объектов COM/ActiveX можно с помощью функции CreateObject (см. Help по VBScript) Вопрос: Можно ли редактировать библиотеки?Ответ: Начиная с версии QTP 9.0, библиотеки можно редактировать и отлаживать в QTP. Открыть библиотеку можно через меню File либо Resources>Associated Functional Libraries>… (если библиотека ассоциирована с открытым в QTP тестом). Есть одна тонкость, связанная с форматом библиотек — начиная с QTP 9.0, QTP предпочитает хранить библиотеки в формат Unicode (то есть, при некоторых условиях он автоматически преобразует формат библиотеки в Unicode, и сохраняет её в таком виде. Это следует иметь в виду при хранении тестов QTP в системах версионного хранения). Использование объекта EnvironmentВопрос: Зачем нужен объект Environment?Ответ: Environment — это коллекция типа Dictionary, содержащая пары ключ — значение, которая видна из всех Actions и из библиотек. Кроме того, Environment содержит многие встроенные значения, относящиеся к текущей сессии исполнения теста, такие как имя пользователя, имя компьютера, имя теста, опции исполнения и т.п. Environment имеет смысл использовать для хранения пользовательских настроек библиотек. Запуск пакетов тестов и использования QTP Automation Object ModelВопрос: Как запустить тест/набор тестов из командной строки?Ответ: Лучше всего использовать COM-интерфейс QTP - Quick Test Pro Automation. Он подробно описан в Help. Пример из Help: '********************************************************************** Dim qtApp 'As QuickTest.Application ' Declare the Application object variable Set qtApp = CreateObject("QuickTest.Application") ' Create the Application object ' Set QuickTest run options qtApp.Options.Run.CaptureForTestResults = "OnError" qtApp.Open "C:\Tests\Test1", True ' Open the test in read-only mode ' set run settings for the test Set qtResultsOpt = CreateObject("QuickTest.RunResultsOptions") ' Create the Run Results Options object qtTest.Run qtResultsOpt ' Run the test MsgBox qtTest.LastRunResults.Status ' Check the results of the test run Set qtResultsOpt = Nothing ' Release the Run Results Options object Кроме того, существует утилита Multi Test Manager, поставляемая в составе пакета QTP Plus (входит в QTP, но устанавливается отдельно). Multi Test Manager Undocumented featuresВопрос: Можно ли использовать HTML в логах?Ответ: Штатными средствами — нельзя. Но если в тексте параметра Description использовать подстроку "&", то описание события показывается в виде HTML. То есть, можно использовать форматирование, вставлять ссылки, делать таблицы, и т.п. Пример: Reporter.ReportEvent micDone, "Test HTML reporting", "<DIV style='font-size: 7pt; color: white'>&</DIV><P style='text-align:left'><B>Test</B> <I>HTML</I> Reporting" |