SlideShare a Scribd company logo
1 of 27
Функциональное тестирование с
помощью Selenium


    Ребров Андрей
    Luxoft
@andrebrov
Задачи
• Нужно иметь возможность проводить
  регрессию в короткий период времени
• Тесты должны быть простыми, чтобы их
  можно было легко
  написать/дописать/переписать
• Поддержка тестов не должна занимать
  много времени
Необходимые инструменты
• Тестовый фреймворк
• Фреймворк функционального тестирования
• CI Server
•+ удобная IDE, понятный генератор отчетов,
удобный язык программирования...
Что взяли мы
•   TestNG
•   Selenium 2 / WebDriver
•   Spring
•   IntelliJ IDEA
•   Jenkins
•   Набор самописных утилит
Почему TestNG
•   Удобная работа с данными - @DataProvider
•   Разбиение тестов по группам
•   Многопоточность «из коробки»
•   «Фабрика» тестов
Почему WebDriver
•   Java-фреймворк
•   Абстракция на уровне PageObject
•   Работа с IE & FF
•   Активно развивается
Зачем Spring?
• Облегчение работы с базами данных
• Необходима интеграция с различными
  сервисами в рамках тестов
• IoC
Этапы создания тестовой
платформы
Создание базового тестового класса
public abstract class AbstractSeleniumTestClass extends AbstractTestNGSpringContextTests {

    @Autowired
    private WebDriver driver;

    @BeforeMethod(alwaysRun = true)
    public void printTestName(Method method) {}

    @AfterMethod(alwaysRun = true)
    public void clearCookies(Method method) throws Exception {}

    protected WebDriver getWebDriver() {}

    public SearchPage loadLemAndLogin() {}
}
Создание базовой web-страницы
public abstract class AbstractPage extends LoadableComponent<LoginPage> {

    public AbstractPage(WebDriver driver) {
      this.driver = driver;
      this.wait = new WebDriverWait(driver, DEFAULT_TIMEOUT);
      PageFactory.initElements(driver, this);
    }

    protected abstract By getPageLoadedCheckElementLocator();

    // Primitive actions
    protected void clickOn(WebElement webElement) {}
    protected void type(WebElement webElement, String text) {}

    // Keys
    protected void pressEnter(WebElement webElement) {}
    protected void pressRight(WebElement webElement) {}
    // Autocomplete
    public void fillAutocomplete(WebElement webElement, String text) {}

    // Waits
    public WebElement waitUntilFound(final By by) {}
}
Описание web-страницы
public class LoginPage extends AbstractPage {

    private static final Logger log = Logger.getLogger(LoginPage.class);

    @FindBy(xpath = "//input[@name='USER']")
    private WebElement usernameInput;
    @FindBy(xpath = "//input[@name='PASSWORD']")
    private WebElement passwordInput;
    @FindBy(xpath = "//input[@class='Button']")
    private WebElement loginButton;


    @Override
    protected By getPageLoadedCheckElementLocator() {}

    public LoginPage(WebDriver driver) {
      super(driver);
    }

    @Override
    protected void isLoaded() throws Error {}

    public SearchPage login() {}

}
Вынесение данных в DataProvider

public class SearchDataProvider {

    @DataProvider
    public static Object[][] searchTypes() {
      Object[][] result = new Object[4][1];
      result[0][0] = "BEGINS_WITH";
      result[1][0] = "CONTAINS";
      result[2][0] = "CONTAINS_SUBSTRING";
      result[3][0] = "SOUNDS_LIKE";
      return result;
    }

}
Refactoring
• Вынесение текстовых констант из классов
  страниц
• Группировка DataProvider`ов в классы
Подключение базы данных
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-
method="close">
  <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
  <property name="url" value=""/>
  <property name="username" value=""/>
  <property name="password" value=""/>
  <property name="maxActive" value="10"/>
</bean>

<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemp
late">
<constructor-arg ref="dataSource"/>
</bean>
Работа с базой внутри
DataProvider`ов
@Component
public class SearchByAlternateNameDataProvider {
           private static DataProviderGenerator dataProviderGenerator;

@Autowired
public void setDataProviderGenerator(DataProviderGenerator dataProviderGenerator) {
SearchByAlternateNameDataProvider.dataProviderGenerator = dataProviderGenerator;
}

 @DataProvider
 public static Object[][] alternateNameAndNonSuitableCOI() {
  return dataProviderGenerator.generatePairStringString("select …" + Config.DATA_COUNT);
 }
}

@Component
public class DataProviderGenerator {
           @Autowired
private TestingJdbcTemplate testingJdbcTemplate;

public Object[][] generatePairStringString(String sql) {}

}
Хинт 1 – WebDriver как SpringBean
@Configuration
public class SeleniumConfiguration {
@Autowired
private WebDriver driver;

public @Bean WebDriver driver() {}

@PreDestroy
public void cleanUp() {
   try {
      driver.quit();
   } catch (Throwable e) {
     e.printStackTrace();
   }
 }
}
Хинт 2 – TestFactory для похожих
тестов
public class SearchTestFactory {

    @Factory(dataProvider = "searchTypes", dataProviderClass = SearchDataProvider.class)
    public Object[] createTest(String searchType) {
      return new Object[]{new GenericSearchTest(searchType)};
    }
}

public class GenericSearchTest extends AbstractSeleniumTest {
private String searchType;

public GenericSearchByLegalNameCOITest(String searchType) {
  this.searchType = searchType;
}
@Test(dataProvider = "legalNamesAndCountries", dataProviderClass = SearchTestFactory.class)
@JiraIssue(number = “SRC-19")
public void test(String param1, String param2) {}

}
Хинт 3 – Unit-тест как тест-кейс
 SearchPage searchPage = loadAndLogin();
 searchPage.setLegalNameSearchType(searchType);
 searchPage.setLegalNameSearchParam(legalName);
 SearchResultPage searchResultPage = searchPage.submit();
 assertIsSortedByLegalName(searchResultPage);
Хинт 4 – Подключаем javascript
public void waitForAjaxComplete() {
log.verbose("waiting for ajax completion");
  wait.until(new ExpectedCondition<Boolean>() {
     public Boolean apply(WebDriver driver) {
       return (Boolean) js.executeScript("return $.active == 0");
     }
  });
log.verbose("All ajax calls are complete");
}
Подключаем Jenkins
• Используем возможность запуска через
  maven
• Подключаем отчеты от TestNG и видим
  результаты регрессии
• Запуск тестов по расписанию / установке
  новой версии / …
Куда двигаться дальше
• Создание профилей тестирования (smokem
  full, search)
• Selenium Grid и многопоточность
• 1 подход – разные типы приложений
  (WebService, ETL, ...)
• End-to-end тестирование
• Андрей Ребров
• andrebrov@gmail.com
     • @andrebrov

More Related Content

What's hot

Java осень 2014 занятие 8
Java осень 2014 занятие 8Java осень 2014 занятие 8
Java осень 2014 занятие 8Technopark
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиГлеб Тарасов
 
JS утиліти WordPress на практиці
JS утиліти WordPress на практиціJS утиліти WordPress на практиці
JS утиліти WordPress на практиціShtrih Sruleg
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8Technopark
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6Technopark
 
2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb Spock2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb SpockBohdan Danyliuk
 
RxJava + Retrofit
RxJava + RetrofitRxJava + Retrofit
RxJava + RetrofitDev2Dev
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.Igor Shkulipa
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJSYura Bogdanov
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)Noveo
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.Igor Shkulipa
 
Живые приложения с Rx
Живые приложения с RxЖивые приложения с Rx
Живые приложения с RxGoSharp
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Fedor Lavrentyev
 
Android - 13 - Database
Android - 13 - DatabaseAndroid - 13 - Database
Android - 13 - DatabaseNoveo
 
Лекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderЛекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderАлександр Брич
 
Приложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefestПриложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefestActis Wunderman
 
Cookies, session и другое в JSP
Cookies, session и другое в JSPCookies, session и другое в JSP
Cookies, session и другое в JSPUnguryan Vitaliy
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: PromisesRAMBLER&Co
 

What's hot (20)

Java осень 2014 занятие 8
Java осень 2014 занятие 8Java осень 2014 занятие 8
Java осень 2014 занятие 8
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с данными
 
JS утиліти WordPress на практиці
JS утиліти WordPress на практиціJS утиліти WordPress на практиці
JS утиліти WordPress на практиці
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6
 
2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb Spock2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb Spock
 
RxJava + Retrofit
RxJava + RetrofitRxJava + Retrofit
RxJava + Retrofit
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJS
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.
 
Живые приложения с Rx
Живые приложения с RxЖивые приложения с Rx
Живые приложения с Rx
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
JDBC
JDBCJDBC
JDBC
 
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
 
Android - 13 - Database
Android - 13 - DatabaseAndroid - 13 - Database
Android - 13 - Database
 
Лекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderЛекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, Loader
 
Приложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefestПриложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefest
 
Cookies, session и другое в JSP
Cookies, session и другое в JSPCookies, session и другое в JSP
Cookies, session и другое в JSP
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: Promises
 

Similar to вебинар - функциональное тестирование с использованием Selenium 2 и TestNG

Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Andrey Rebrov
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobileUA Mobile
 
iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationAndrii Dzynia
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NETVitaly Baum
 
Виталий Каторгин, Wamba
Виталий Каторгин, WambaВиталий Каторгин, Wamba
Виталий Каторгин, WambaOntico
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый стартAntonio
 
Приемочные тесты на огурце
Приемочные тесты на огурцеПриемочные тесты на огурце
Приемочные тесты на огурцеAlexander Byndyu
 
SECON'2016. Иовлев Роман, JDI is UI Automation Future
SECON'2016. Иовлев Роман, JDI is UI Automation FutureSECON'2016. Иовлев Роман, JDI is UI Automation Future
SECON'2016. Иовлев Роман, JDI is UI Automation FutureSECON
 
Automation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAutomation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAndrey Rebrov
 
Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...
Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...
Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...Andrey Rebrov
 
Mikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsMikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsCiklum
 
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Dev_Party
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПKirill Chebunin
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverIgor Khrol
 
Простой и кросс-платформенный WEB-сервер на .NET
Простой и кросс-платформенный WEB-сервер на .NETПростой и кросс-платформенный WEB-сервер на .NET
Простой и кросс-платформенный WEB-сервер на .NETMikhail Shcherbakov
 
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgДело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgIT61
 
Java осень 2012 лекция 5
Java осень 2012 лекция 5Java осень 2012 лекция 5
Java осень 2012 лекция 5Technopark
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Noveo
 
Django Rest Framework vs Graph Ql
Django Rest Framework vs Graph QlDjango Rest Framework vs Graph Ql
Django Rest Framework vs Graph QlAttract Group
 

Similar to вебинар - функциональное тестирование с использованием Selenium 2 и TestNG (20)

Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobile
 
iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test Automation
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NET
 
Виталий Каторгин, Wamba
Виталий Каторгин, WambaВиталий Каторгин, Wamba
Виталий Каторгин, Wamba
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый старт
 
Приемочные тесты на огурце
Приемочные тесты на огурцеПриемочные тесты на огурце
Приемочные тесты на огурце
 
SECON'2016. Иовлев Роман, JDI is UI Automation Future
SECON'2016. Иовлев Роман, JDI is UI Automation FutureSECON'2016. Иовлев Роман, JDI is UI Automation Future
SECON'2016. Иовлев Роман, JDI is UI Automation Future
 
Automation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAutomation Functional Testing in Agile Projects
Automation Functional Testing in Agile Projects
 
Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...
Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...
Автоматизируйте это немедленно или коллекция инструментов автотестирования с ...
 
Mikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsMikhail Valkov_Antipatterns
Mikhail Valkov_Antipatterns
 
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
 
Jsfwdays 2013-2
Jsfwdays 2013-2Jsfwdays 2013-2
Jsfwdays 2013-2
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriver
 
Простой и кросс-платформенный WEB-сервер на .NET
Простой и кросс-платформенный WEB-сервер на .NETПростой и кросс-платформенный WEB-сервер на .NET
Простой и кросс-платформенный WEB-сервер на .NET
 
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgДело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
 
Java осень 2012 лекция 5
Java осень 2012 лекция 5Java осень 2012 лекция 5
Java осень 2012 лекция 5
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
 
Django Rest Framework vs Graph Ql
Django Rest Framework vs Graph QlDjango Rest Framework vs Graph Ql
Django Rest Framework vs Graph Ql
 

More from Andrey Rebrov

Agile Testing in Enterprise: Way to transform - SQA Days 2014
Agile Testing in Enterprise: Way to transform - SQA Days 2014Agile Testing in Enterprise: Way to transform - SQA Days 2014
Agile Testing in Enterprise: Way to transform - SQA Days 2014Andrey Rebrov
 
Spec By Example or How to teach people talk to each other
Spec By Example or How to teach people talk to each otherSpec By Example or How to teach people talk to each other
Spec By Example or How to teach people talk to each otherAndrey Rebrov
 
Test Automation Canvas
Test Automation CanvasTest Automation Canvas
Test Automation CanvasAndrey Rebrov
 
How engineering practices help business
How engineering practices help businessHow engineering practices help business
How engineering practices help businessAndrey Rebrov
 
Don’t turn your logs into cuneiform
Don’t turn your logs into cuneiformDon’t turn your logs into cuneiform
Don’t turn your logs into cuneiformAndrey Rebrov
 
DevOps tools cargo tools
DevOps tools cargo toolsDevOps tools cargo tools
DevOps tools cargo toolsAndrey Rebrov
 
Agile тестирование в enterpise проектов: путь трансформации
Agile тестирование в enterpise проектов: путь трансформацииAgile тестирование в enterpise проектов: путь трансформации
Agile тестирование в enterpise проектов: путь трансформацииAndrey Rebrov
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayAndrey Rebrov
 
Test Automation Canvas - не наступайте на глабли автоматизации
Test Automation Canvas - не наступайте на глабли автоматизацииTest Automation Canvas - не наступайте на глабли автоматизации
Test Automation Canvas - не наступайте на глабли автоматизацииAndrey Rebrov
 
Не превращайте ваши логи в клинопись
Не превращайте ваши логи в клинописьНе превращайте ваши логи в клинопись
Не превращайте ваши логи в клинописьAndrey Rebrov
 
Карго культ инструментов в DevOps
Карго культ инструментов в DevOpsКарго культ инструментов в DevOps
Карго культ инструментов в DevOpsAndrey Rebrov
 
как инженерные практики помогают экономить бизнесу
как инженерные практики помогают экономить бизнесукак инженерные практики помогают экономить бизнесу
как инженерные практики помогают экономить бизнесуAndrey Rebrov
 
грабли автоматизации тестирования мобильного веба с помощью Selenium 2
грабли автоматизации тестирования мобильного веба с помощью Selenium 2грабли автоматизации тестирования мобильного веба с помощью Selenium 2
грабли автоматизации тестирования мобильного веба с помощью Selenium 2Andrey Rebrov
 
DevOps от и до - что, зачем и почему
DevOps от и до - что, зачем и почемуDevOps от и до - что, зачем и почему
DevOps от и до - что, зачем и почемуAndrey Rebrov
 
Agile Testing: вопросы и ответы
Agile Testing: вопросы и ответыAgile Testing: вопросы и ответы
Agile Testing: вопросы и ответыAndrey Rebrov
 
DevOps модное слово или следующая ступень эволюции
DevOps модное слово или следующая ступень эволюцииDevOps модное слово или следующая ступень эволюции
DevOps модное слово или следующая ступень эволюцииAndrey Rebrov
 
Как научить людей общаться с помощью Spec By Example
Как научить людей общаться с помощью Spec By ExampleКак научить людей общаться с помощью Spec By Example
Как научить людей общаться с помощью Spec By ExampleAndrey Rebrov
 
Rebrov selenium camp2013
Rebrov selenium camp2013Rebrov selenium camp2013
Rebrov selenium camp2013Andrey Rebrov
 
Курс молодого бойца-автоматизатора - как остаться в живых и стать ветераном
Курс молодого бойца-автоматизатора - как остаться в живых и стать ветераномКурс молодого бойца-автоматизатора - как остаться в живых и стать ветераном
Курс молодого бойца-автоматизатора - как остаться в живых и стать ветераномAndrey Rebrov
 

More from Andrey Rebrov (20)

Agile Testing in Enterprise: Way to transform - SQA Days 2014
Agile Testing in Enterprise: Way to transform - SQA Days 2014Agile Testing in Enterprise: Way to transform - SQA Days 2014
Agile Testing in Enterprise: Way to transform - SQA Days 2014
 
Spec By Example or How to teach people talk to each other
Spec By Example or How to teach people talk to each otherSpec By Example or How to teach people talk to each other
Spec By Example or How to teach people talk to each other
 
Test Automation Canvas
Test Automation CanvasTest Automation Canvas
Test Automation Canvas
 
How engineering practices help business
How engineering practices help businessHow engineering practices help business
How engineering practices help business
 
Don’t turn your logs into cuneiform
Don’t turn your logs into cuneiformDon’t turn your logs into cuneiform
Don’t turn your logs into cuneiform
 
DevOps tools cargo tools
DevOps tools cargo toolsDevOps tools cargo tools
DevOps tools cargo tools
 
Agile Games
Agile GamesAgile Games
Agile Games
 
Agile тестирование в enterpise проектов: путь трансформации
Agile тестирование в enterpise проектов: путь трансформацииAgile тестирование в enterpise проектов: путь трансформации
Agile тестирование в enterpise проектов: путь трансформации
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps way
 
Test Automation Canvas - не наступайте на глабли автоматизации
Test Automation Canvas - не наступайте на глабли автоматизацииTest Automation Canvas - не наступайте на глабли автоматизации
Test Automation Canvas - не наступайте на глабли автоматизации
 
Не превращайте ваши логи в клинопись
Не превращайте ваши логи в клинописьНе превращайте ваши логи в клинопись
Не превращайте ваши логи в клинопись
 
Карго культ инструментов в DevOps
Карго культ инструментов в DevOpsКарго культ инструментов в DevOps
Карго культ инструментов в DevOps
 
как инженерные практики помогают экономить бизнесу
как инженерные практики помогают экономить бизнесукак инженерные практики помогают экономить бизнесу
как инженерные практики помогают экономить бизнесу
 
грабли автоматизации тестирования мобильного веба с помощью Selenium 2
грабли автоматизации тестирования мобильного веба с помощью Selenium 2грабли автоматизации тестирования мобильного веба с помощью Selenium 2
грабли автоматизации тестирования мобильного веба с помощью Selenium 2
 
DevOps от и до - что, зачем и почему
DevOps от и до - что, зачем и почемуDevOps от и до - что, зачем и почему
DevOps от и до - что, зачем и почему
 
Agile Testing: вопросы и ответы
Agile Testing: вопросы и ответыAgile Testing: вопросы и ответы
Agile Testing: вопросы и ответы
 
DevOps модное слово или следующая ступень эволюции
DevOps модное слово или следующая ступень эволюцииDevOps модное слово или следующая ступень эволюции
DevOps модное слово или следующая ступень эволюции
 
Как научить людей общаться с помощью Spec By Example
Как научить людей общаться с помощью Spec By ExampleКак научить людей общаться с помощью Spec By Example
Как научить людей общаться с помощью Spec By Example
 
Rebrov selenium camp2013
Rebrov selenium camp2013Rebrov selenium camp2013
Rebrov selenium camp2013
 
Курс молодого бойца-автоматизатора - как остаться в живых и стать ветераном
Курс молодого бойца-автоматизатора - как остаться в живых и стать ветераномКурс молодого бойца-автоматизатора - как остаться в живых и стать ветераном
Курс молодого бойца-автоматизатора - как остаться в живых и стать ветераном
 

вебинар - функциональное тестирование с использованием Selenium 2 и TestNG

  • 3. Задачи • Нужно иметь возможность проводить регрессию в короткий период времени • Тесты должны быть простыми, чтобы их можно было легко написать/дописать/переписать • Поддержка тестов не должна занимать много времени
  • 4. Необходимые инструменты • Тестовый фреймворк • Фреймворк функционального тестирования • CI Server •+ удобная IDE, понятный генератор отчетов, удобный язык программирования...
  • 5. Что взяли мы • TestNG • Selenium 2 / WebDriver • Spring • IntelliJ IDEA • Jenkins • Набор самописных утилит
  • 6. Почему TestNG • Удобная работа с данными - @DataProvider • Разбиение тестов по группам • Многопоточность «из коробки» • «Фабрика» тестов
  • 7. Почему WebDriver • Java-фреймворк • Абстракция на уровне PageObject • Работа с IE & FF • Активно развивается
  • 8. Зачем Spring? • Облегчение работы с базами данных • Необходима интеграция с различными сервисами в рамках тестов • IoC
  • 11. public abstract class AbstractSeleniumTestClass extends AbstractTestNGSpringContextTests { @Autowired private WebDriver driver; @BeforeMethod(alwaysRun = true) public void printTestName(Method method) {} @AfterMethod(alwaysRun = true) public void clearCookies(Method method) throws Exception {} protected WebDriver getWebDriver() {} public SearchPage loadLemAndLogin() {} }
  • 13. public abstract class AbstractPage extends LoadableComponent<LoginPage> { public AbstractPage(WebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, DEFAULT_TIMEOUT); PageFactory.initElements(driver, this); } protected abstract By getPageLoadedCheckElementLocator(); // Primitive actions protected void clickOn(WebElement webElement) {} protected void type(WebElement webElement, String text) {} // Keys protected void pressEnter(WebElement webElement) {} protected void pressRight(WebElement webElement) {} // Autocomplete public void fillAutocomplete(WebElement webElement, String text) {} // Waits public WebElement waitUntilFound(final By by) {} }
  • 15. public class LoginPage extends AbstractPage { private static final Logger log = Logger.getLogger(LoginPage.class); @FindBy(xpath = "//input[@name='USER']") private WebElement usernameInput; @FindBy(xpath = "//input[@name='PASSWORD']") private WebElement passwordInput; @FindBy(xpath = "//input[@class='Button']") private WebElement loginButton; @Override protected By getPageLoadedCheckElementLocator() {} public LoginPage(WebDriver driver) { super(driver); } @Override protected void isLoaded() throws Error {} public SearchPage login() {} }
  • 16. Вынесение данных в DataProvider public class SearchDataProvider { @DataProvider public static Object[][] searchTypes() { Object[][] result = new Object[4][1]; result[0][0] = "BEGINS_WITH"; result[1][0] = "CONTAINS"; result[2][0] = "CONTAINS_SUBSTRING"; result[3][0] = "SOUNDS_LIKE"; return result; } }
  • 17. Refactoring • Вынесение текстовых констант из классов страниц • Группировка DataProvider`ов в классы
  • 18. Подключение базы данных <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy- method="close"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"/> <property name="url" value=""/> <property name="username" value=""/> <property name="password" value=""/> <property name="maxActive" value="10"/> </bean> <bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemp late"> <constructor-arg ref="dataSource"/> </bean>
  • 19. Работа с базой внутри DataProvider`ов
  • 20. @Component public class SearchByAlternateNameDataProvider { private static DataProviderGenerator dataProviderGenerator; @Autowired public void setDataProviderGenerator(DataProviderGenerator dataProviderGenerator) { SearchByAlternateNameDataProvider.dataProviderGenerator = dataProviderGenerator; } @DataProvider public static Object[][] alternateNameAndNonSuitableCOI() { return dataProviderGenerator.generatePairStringString("select …" + Config.DATA_COUNT); } } @Component public class DataProviderGenerator { @Autowired private TestingJdbcTemplate testingJdbcTemplate; public Object[][] generatePairStringString(String sql) {} }
  • 21. Хинт 1 – WebDriver как SpringBean @Configuration public class SeleniumConfiguration { @Autowired private WebDriver driver; public @Bean WebDriver driver() {} @PreDestroy public void cleanUp() { try { driver.quit(); } catch (Throwable e) { e.printStackTrace(); } } }
  • 22. Хинт 2 – TestFactory для похожих тестов public class SearchTestFactory { @Factory(dataProvider = "searchTypes", dataProviderClass = SearchDataProvider.class) public Object[] createTest(String searchType) { return new Object[]{new GenericSearchTest(searchType)}; } } public class GenericSearchTest extends AbstractSeleniumTest { private String searchType; public GenericSearchByLegalNameCOITest(String searchType) { this.searchType = searchType; } @Test(dataProvider = "legalNamesAndCountries", dataProviderClass = SearchTestFactory.class) @JiraIssue(number = “SRC-19") public void test(String param1, String param2) {} }
  • 23. Хинт 3 – Unit-тест как тест-кейс SearchPage searchPage = loadAndLogin(); searchPage.setLegalNameSearchType(searchType); searchPage.setLegalNameSearchParam(legalName); SearchResultPage searchResultPage = searchPage.submit(); assertIsSortedByLegalName(searchResultPage);
  • 24. Хинт 4 – Подключаем javascript public void waitForAjaxComplete() { log.verbose("waiting for ajax completion"); wait.until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return (Boolean) js.executeScript("return $.active == 0"); } }); log.verbose("All ajax calls are complete"); }
  • 25. Подключаем Jenkins • Используем возможность запуска через maven • Подключаем отчеты от TestNG и видим результаты регрессии • Запуск тестов по расписанию / установке новой версии / …
  • 26. Куда двигаться дальше • Создание профилей тестирования (smokem full, search) • Selenium Grid и многопоточность • 1 подход – разные типы приложений (WebService, ETL, ...) • End-to-end тестирование
  • 27. • Андрей Ребров • andrebrov@gmail.com • @andrebrov