Доброго вам времени суток.
Это будет моя самая первая запись.
Наверное всем QA инженерам известна проблема автоматизации flash-приложений. Копий здесь сломано немало, и так сложилось, что новые инструменты на этом поприще я рассматриваю с предубеждением: "или платный, или сложно установить, или неудобный".
И вот пару недель назад я узнал про Automated UI Tester for Adobe ActionScript или если кратко - Genie. Как понятно из названия – это инструмент тестирования флеш - приложений. В этот раз предубеждения были лишними, Genie - весьма интересный инструмент. Его легко установить, он бесплатный и довольно удобный. Я не хочу повторяться в описаниях продукта и, если вы не знакомы с Genie, тогда, пожалуйста, почитайте вот эти замечательные статьи:
А если уже прочитали, то давайте продолжим. Мы уже знаем, как запустить отдельный скрипт Genie. Но давайте представим, что мы тестируем онлайн-игру. Или несколько игр. Нам бы хотелось сначала открыть страницу с игрой, прокрутить скрипт, а потом как-то посмотреть, что флешка корректно взаимодействует со страницей. Тогда хорошо бы и Genie сервер запускать и останавливать автоматически. Да и вообще неплохо бы обернуть всё нами написанное в тесты под какими-нибудь jUnit или TestNG. Давайте попробуем. Пусть логику флеша исполняет Genie, логику веб страницы поручим Webdriver’у, и всё это обернём в тесты под TestNG.
cd Libs\GenieServer\start "GenieServer" java -Dfile.encoding=UTF-8 -Xms512M -Xmx512M -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -jar GenieSocketServer.jar
exit 0
Поступим точно также и с остановкой сервера. Напишем командный файлик stopServer.cmd:
Теперь сделаем методы запуска и остановки startGenieServer и stopGenieServer. Будем вызывать их из традиционных конфигурационных методов Setup и TearDown (туда же можно добавить запуск браузера и разные прочие приготовления). Пометим их аннотациями @BeforeTest и @AfterTest.
Это будет моя самая первая запись.
Наверное всем QA инженерам известна проблема автоматизации flash-приложений. Копий здесь сломано немало, и так сложилось, что новые инструменты на этом поприще я рассматриваю с предубеждением: "или платный, или сложно установить, или неудобный".
И вот пару недель назад я узнал про Automated UI Tester for Adobe ActionScript или если кратко - Genie. Как понятно из названия – это инструмент тестирования флеш - приложений. В этот раз предубеждения были лишними, Genie - весьма интересный инструмент. Его легко установить, он бесплатный и довольно удобный. Я не хочу повторяться в описаниях продукта и, если вы не знакомы с Genie, тогда, пожалуйста, почитайте вот эти замечательные статьи:
Или, например, мануал.
Там вы найдёте плюсы продукта, его установку и азы работы.
1.
Автоматический запуск и
остановка Genie
сервера.
Давайте изначально условимся, что наш проект лежит по вот такому пути: C:\Projects\Java\GenieTestNG. Чтобы запустить сервер Genie, нам достаточно запустить файл GenieSocketServer.jar. Этот файл входит в пакет файлов Genie (папочка GenieServer). Можно создать в нашем проекте папочку Libs и скопировать туда всю папку GenieServer. После этого добавим в проект командный файлик runServer.cmd. Он будет запускать файл GenieSocketServer.jar. Наш командный файл будет выглядеть так:
cd Libs\GenieServer\start "GenieServer" java -Dfile.encoding=UTF-8 -Xms512M -Xmx512M -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -jar GenieSocketServer.jar
exit 0
taskkill
/FI
"WINDOWTITLE eq GenieServer"
exit 0
Команда exit
0 нужна для того, чтобы окошко командной строки закрылось после выполнения всех команд. Иначе оно будет висеть и раздражать нас. exit 0
Теперь сделаем методы запуска и остановки startGenieServer и stopGenieServer. Будем вызывать их из традиционных конфигурационных методов Setup и TearDown (туда же можно добавить запуск браузера и разные прочие приготовления). Пометим их аннотациями @BeforeTest и @AfterTest.
Эти аннотации означают, что метод будет запущен один раз перед проходом всех тестов (не перед каждым тестом, а именно 1 раз перед всеми тестами) и один раз после прохода всех тестов. Больше про аннотации можно почитать здесь.
Тесты, как и базовый класс сложим в пакет com.blogspot.testerstorehouse.tests
Тесты, как и базовый класс сложим в пакет com.blogspot.testerstorehouse.tests
package
com.blogspot.testerstorehouse.tests;
import
java.io.IOException;
import
org.testng.annotations.AfterTest;
import
org.testng.annotations.BeforeTest;
public
class
TestsBase {
@BeforeTest
public
void
Setup(){
startGenieServer();
}
@AfterTest
public
void
TearDown(){
stopGenieServer();
}
private
void
startGenieServer() {
ExecuteBatch("cmd
/c start runServer.cmd");
}
private
void
stopGenieServer() {
ExecuteBatch("cmd
/c start stopServer.cmd");
}
private
void
ExecuteBatch(String command){
try
{
Runtime.getRuntime().exec(command);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
2.
Запуск Genie
скриптов.
Вариант запуска скриптов, предложенный в мануале, нас не вполне устраивает. Нам не нужна отдельная конфигурация запуска под каждый Genie-скрипт. Нужно чтобы мы могли запускать любой скрипт, внутри тестов, передавая путь к скрипту, как параметр. Давайте создадим класс GenieScriptsExecutor и в нём метод ExecuteScript. Создадим их в отдельном пакете com.blogspot.testerstorehouse.genieHelper.
package
com.blogspot.testerstorehouse.geniehelper;
import
com.adobe.genie.executor.Executor;
public
class
GenieScriptsExecutor {
public
static
void
ExecuteScript(String path) {
String[]
path_arr = new
String[]{path};
try
{
Executor.startExecution(path_arr);
}
catch
(ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Я умолчал, что предварительно, нужно было добавить файл Executor.jar в Buildpath нашего проекта. Этот файлик находится среди других файлов пакета Genie: Genie-binary\Genie\GenieScripts\Executor.jar.
Вернёмся к коду. Команда выполнения скрипта будет теперь выглядеть так:
GenieScriptsExecutor.ExecuteScript("Path to GenieScript.class");
Я умолчал, что предварительно, нужно было добавить файл Executor.jar в Buildpath нашего проекта. Этот файлик находится среди других файлов пакета Genie: Genie-binary\Genie\GenieScripts\Executor.jar.
Вернёмся к коду. Команда выполнения скрипта будет теперь выглядеть так:
GenieScriptsExecutor.ExecuteScript("Path to GenieScript.class");
3.
Связка с Webdriver.
Мы уже умеем выполнять нужные нам скрипты внутри кода. Можно оборачивать их в любую нужную нам логику. Например - в тесте нужно открыть страницу с игрой, сделать несколько действий во флешке, затем проверить, что на странице появился нужный нам элемент с локатором id=“gameEnd”. В отдельном пакете com.blogspot.testerstorehouse.webdriverHelper создадим класс WebdriverHelper с вспомогательными методами:
package
com.blogspot.testerstorehouse.webdriverhelper;
import
org.openqa.selenium.By;
import
org.openqa.selenium.Capabilities;
import
org.openqa.selenium.WebDriver;
import
org.openqa.selenium.WebElement;
import
org.openqa.selenium.firefox.FirefoxDriver;
import
org.openqa.selenium.remote.DesiredCapabilities;
public
class
WebdriverHelper {
private
static
WebDriver driver
= null;
private
static
Capabilities HelperCapabilities=null;
//Метод
позволяет
запустить
браузер
с какими-то
особыми
настройками
public
static
void
createCapabilities(DesiredCapabilities capabilities){
HelperCapabilities=capabilities;
}
//Метод
ленивого
обращения
к драйверу
public
static
WebDriver getDriver(){
if
(driver==null){
driver
= new
FirefoxDriver(HelperCapabilities);
}
return
driver;
}
//Остановка
вебдрайвера,
закрытие
браузера
public
static
void
teardown(){
if(getDriver()!=null){
getDriver().close();
getDriver().quit();
}
}
//Поиск
элемента
public
static
WebElement findElement(By locator){
return
getDriver().findElement(locator);
}
//Проверка
наличия
элемента
на
странице
public
static
boolean
isElementPresent(By locator){
if
(getDriver().findElements(locator).size()>0){
return
true;
}
return
false;
}
//Ожидание
появления
элемента
public
static
void
waitforElementDisplayed(By locator) {
try
{
for
(int
second = 0; second<10; second++) {
if
(isElementPresent(locator)){
if
(getDriver().findElement(locator).isDisplayed()){
break;
}
}
Thread.sleep(1000);
}
}
catch
(Exception e) {e.printStackTrace();}
}
//Открытие
страницы
public
static
void
openUrl(String testUrl){
getDriver().get(testUrl);
}
}
Добавим запуск и остановку вебдрайвера в наши Setup и Teardown:
public
WebDriver driver;
@BeforeTest
public
void
Setup(){
startGenieServer();
driver
= WebdriverHelper.getDriver();
}
@AfterTest
public
void
TearDown(){
stopGenieServer();
driver.close();
driver.quit();
}
Теперь в пакете com.blogspot.testerstorehouse.tests cоздадим класс GameTests с тестовыми методами:
package
com.blogspot.testerstorehouse.tests;
import
org.openqa.selenium.By;
import
com.blogspot.testerstorehouse.geniehelper.GenieScriptsExecutor;
import
com.blogspot.testerstorehouse.webdriverhelper.WebdriverHelper;
public
class
GameTests extends
TestsBase{
public
void
testGame(){
WebdriverHelper.openUrl("http://testsite/gamepage/");
GenieScriptsExecutor.ExecuteScript("Path to Genie Script .class");
WebdriverHelper.waitforElementDisplayed(By.id("gameEnd"));
}
}
Спасибо вам, Дмитрий, за статью.
ОтветитьУдалитьСтолкнулась с проблемой автоматизации флеша, а тут такое прекрасное описание.
Но, как у человека далекого от программирования, у меня появилось несколько вопросов.
К какому классу принадлежат наши методы startGenieServer и stopGenieServer?
Несмотря на то, что я добавила Executor.jar в Buildpath, Executor все равно не может быть выполненным. Что я пропустила из виду?
Была бы очень признательна за помощь.
Добрый день.
ОтветитьУдалитьНе за что.
Вообще сейчас, после некоторого времени работы с Genie, я понял, что статью надо переписать. Есть куча недочётов. Например, тестнг не будет обрабатывать ошибки в скриптах в такой реализации, но есть вариант - парсить результаты скрипта. Я перепишу эту статью, с пояснением. Есть ещё некоторые моменты, которые надо осветить и раз вам это нужно, то я потороплюсь.
Давайте сейчас разберёмся с вашей проблемой.
Методы запуска и остановки джини можно положить прямо в том же классе, где и остальные тесты. Можно вынести в отдельный класс TestBase. Ваши классы с тестами могут наследовать класс TestBase, к примеру. Там же сложите какие-то общие для всех тестов действия.
Например вот так
public class TestBase {
@BeforeTest //Аннотация означает, что этот метод будет выполняться только один раз, перед всей группой тестов.
public void testSetup() throws Exception{
startGenieServer();
}
@AfterTest
public void testTeardown(){
stopGenieServer();
}
}
Ваши тестовые классы будут наследовать класс TestBase:
public class TestsChat extends TestBase{
@Test
public void TestSomething(){
//Здесь тестовая логика
}
}
Касательно второго вопроса.
ОтветитьУдалитьМожете чуть детальнее описать проблему и ошибку?
Спасибо за ответ. А то я было уже отчаялась решить проблему.
ОтветитьУдалитьКасательно второго вопроса.
Я создала класс GenieScriptsExecutor с методом ExecuteScript.
ошибка вываливается на строке:
Executor.startExecution(path_arr);
"Executor can not be resolved"
Хотя сам файлик executor.jar добавила в Buildpath проекта
проблема с executor решилась. нужно было просто перезагрузить eclipse )
ОтветитьУдалитьтеперь с нетерпением буду ждать продолжения статьи. ибо она оказалась действительно полезной.
спасибо.
Пишите, спрашивайте :)
ОтветитьУдалитьЯ успел утром дописать ещё одну статейку по Джини. Посмотрите, может вам будет интересно:
http://testerstorehouse.blogspot.com/2014/06/genie-class.html
Дмитрий, прошла неделя, и мне вновь нужен ваш совет )
ОтветитьУдалитьВозможно ли применять аннотацию testNG внутри самого скрипта джини?
Столкнулась со сл.проблемой: внутри джинни нужно проверить условие, и при его невыполнении остановить тест с ошибкой. Есть ли такая возможность у джинни?
Доброго дня. Я как раз сегодня обновил эту статью. Форматирование ещё пока кривое, правда, но я его поправлю :)
ОтветитьУдалитьСмотрите, какая штука.
Скрипт Genie исполняется внутри своего отдельного потока.Стало быть, любые пойманные им эксепшны перехватываются там же внутри.
Я бы предложил вам использовать
Genie.EXIT_ON_FAILURE = true;
Проверять условия можно с помощью ассертов. Они есть в самом джини
GenieAssertion.assertTrue(message, condition);
Если в Ассерте не выполнится условия, джини обработает эксепшн и остановит выполнение, если .EXIT_ON_FAILURE = true.
Посмотрите вторую часть этой статьи, там есть описание велосипеда, которым можно обернуть джини в тестнг:
http://testerstorehouse.blogspot.com/2014/06/adobe-genie-webdriver-testng-2.html
Пишите, спрашивайте.