Автоматизация Flex-приложений с помощью Selenium RCИгорь Хрол
Немного о себеИгорь ХролСпециализируюсь на автоматизации тестирования с 2006годаИнструменты:Selenium, HP QTP, Watir, TestComplete, JmeterE-mail: khroliz@gmail.com
Что будет в докладе?Немного о проектеКакой стоял выбор для автоматизации Flex’a?Сравнение инструментовВыбранное решение и архитектураTips&TricksТекущие результаты работы
О проектеwww.atg.com (с января 2011-го – часть Oracle)Середина 2009-го – вся UI-автоматизацияна HP QTPКонец 2009-го – первые версии приложения с Flexи решение начать автоматизацию на Selenium
Варианты Flex-автоматизацииHP QTP +  Flex QTP add-inSelenium-Flex API + Selenium RC + JavaFunFX + Watir + Ruby
Результаты оценки – скорость работы (JSP)Цикличное создание-удаление 100 сущностей в JSPВремя выполнения сценария в минутах
Результаты оценки – скорость работы (Flex)Цикличное создание-удаление 100 сущностей вo FlexВремя выполнения сценария в минутахQTP не поддерживает Firefox с Flex
Результаты оценки – скорость работы (Flex)Цикличная навигация по Flex – 100 разВремя выполнения сценария в минутахQTP не поддерживает Firefox с Flex
Недостатки QTPНестабильная работаРаспознавание UI-объектов с учётом практически всей иерархии объектовОтсутствие удобного языка и средств разработки
Схема работы Selenium Flex APISelenium RCКод тест-кейса (С#, Java, Python, Ruby и другое)HTTPБраузерSelenium Coreuser-extensions.jsТестируемое приложениеExternalInterfaceFlex
Поддержка различных браузеровНужна ли вообще?Различные версии IEGoogle Chrome, Safari, Opera…Ну и конечно Firefox
Поддержка различных браузеров – модификации для FirefoxКод тест-кейса (С#, Java, Python, Ruby и другое)Selenium RCHTTPБраузерSelenium Coreuser-extensions.jsТестируемое приложениеExternalInterfaceBridgeFlex
Структура фреймворка - локаторыПодобие ХPath, но не совсемОбщая структура:property:valueproperty1:value1,property2:value2property1:value1/property2:value2property1.subproperty11:value11,property2:value2/property3.subproperty31:value31Примеры…
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/className:BrowsePanel/id:ancestorNavBar/id:dropdownButtonArea/id:nodeText
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/className:BrowsePanel/id:ancestorNavBar/id:dropdownButtonArea/id:nodeText
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/className:BrowsePanel/id:ancestorNavBar/id:dropdownButtonArea/id:nodeText
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/className:BrowsePanel/id:ancestorNavBar/id:dropdownButtonArea/id:nodeText
Пример локатораid:merchandising.manageCommerceAssets0,root.numModalWindows:0/className:BrowsePanel/id:ancestorNavBar/id:dropdownButtonArea/id:nodeText
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabel
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabelid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabel
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabelid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabelid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabel
Пример локатораid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabelid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabelid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabelid:merchandising.manageCommerceAssets_0,root.numModalWindows:0/name:mainPanel/className:HBox,numChildren:2,getChildAt(0).className:PropertyStatusIndicatorPanel,getChildAt(1).getChildAt(0).getChildAt(0).text:SKUs/styleName:defaultPropertyLabel
Структура фреймворкаСоотношение: класс из Flex’a↔класс из Java-фреймворка
Структура фреймворкаJava-класс инициализируется:своим локаторомлокатором контейнера
Структура фреймворка«Склейка» локаторов на уровне базового конструктора
Структура фреймворка - синхронизацияПри обращении к Java-объекту – ждём соответствующего объекта на UIСинхронизации нет???
Tips&Tricks – FlexSpyОсобенности:Запускается внутри флеш-объекта (может вызывать побочные эффекты)Лучше добавить его вызов на какую-нибудь комбинацию клавиш
FlexSpy
Обнаружение свойств объектов FlashInspectorПлагин к FirefoxТребует:Установки FirebugDebug-версию FlashPlayer’а
СложностиАльтернативная разработка Selenium Flex API своими силамиУлучшена система локаторовИсправлено несколько дефектовРазработаны методы для работы с DataGrid’амиРасширено количество вызываемых событийНадеемся скоро это внести в виде своей доли в проект sfapi
Сложности«Нативные» нажатия на кнопки – например для закачивания/скачивания файловРешение: AutoITСоздание выполняемых exe-файловИспользование DLL через JNA
Интеграция с существующим кодом на QTPЦель: выполнение действий во Flex-еиз QTP с помощью существующего Java-кодаАлгоритм:Запуск браузера из Selenium’aСохранение сессииРабота с отрытым браузером из QTPВызов отдельных java-процессов с передачей в них сессии
Результаты~400k строк кода~4500 java-классов (~3500 автоматизированных тест кейсов)Около 5 суток работы тестовРасширяемое решение
Вопросы

автоматизация Flex приложений с помощью selenium rc

Editor's Notes

  • #5 Май 2010 по Gartner – в лидерах 2 решения в eCommerce: ATG и IBM WebSphere Commerce.
  • #8 Watir с FunFX – мы не смогли стабильно автоматизировать эталонный сценарий.Различие технологий Ruby-Java остановило от дальнейшего рассмотрения этого сценария.
  • #12 История про Firefox + WebSphere.Усилия на поддержку кроссбраузерности сократились на Flex.
  • #20 Отсутствует синхронизация в первой ветке if’a.
  • #23 Есть определённая нестабильность.
  • #25 Пример с «Browse…» - ограничения по Security FlashPlayer’a.
  • #27 5-10человеко-лет разработки