Бодрящий микс из selenium и testng- регрессионное...

35
Бодрящий микс из Selenium и TestNG Регрессионное тестирование руками разработчиков Ребров Андрей Luxoft

Upload: andrey-rebrov

Post on 02-Dec-2014

5.042 views

Category:

Technology


11 download

DESCRIPTION

Как-то так происходит, что “на 10 девчонок по статистике 9 ребят”, а точнее на группу из 5-7 разработчиков – 1 тестировщик. Или его нет совсем. Так что очень часто приходится и код писать, и тестировать, а дата релиза все ближе и ближе. В тех случаях, когда мы пишем веб-приложение, помочь в нашей нелегкой судьбе может бодрящий микс из Selenium и TestNG... Как это сделали мы, какие потом получили выводы и результаты — все это я и хочу рассказать и показать

TRANSCRIPT

Page 1: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Бодрящий микс из Selenium и TestNG Регрессионное тестирование руками разработчиков

Ребров АндрейLuxoft

Page 2: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

@andrebrov

Page 3: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Сколько тестировщиков в вашей команде?

Page 4: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков
Page 5: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков
Page 6: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков
Page 7: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Build more overseer! ©

Page 8: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

При этом...

• «У нас agile» - значит, тестирование должно завершиться в том же спринте

• «Люблю короткие релизы»- значит регрессионное тестирование надо делать постоянно

• «Они опять изменили требования!» - значит опять надо менять тесты

Page 9: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Хватит это терпеть!

Page 10: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Задачи

• Нужно иметь возможность проводить регрессию в короткий период времени

• Тесты должны быть простыми, чтобы их можно было легко написать/дописать/переписать

• Поддержка тестов не должна занимать много времени

Page 11: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Необходимые инструменты

• Тестовый фреймворк• Фреймворк функционального тестирования• CI Server+ удобная IDE, понятный генератор отчетов, удобный язык программирования...

Page 12: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Что взяли мы

• TestNG• Selenium 2 / WebDriver• Spring• IntelliJ IDEA• Jenkins• Набор самописных утилит

Page 13: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Почему TestNG

• Удобная работа с данными - @DataProvider• Разбиение тестов по группам• Многопоточность «из коробки»• «Фабрика» тестов

Page 14: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Почему WebDriver

• Java-фреймворк• Абстракция на уровне PageObject• Работа с IE & FF• Активно развивается

Page 15: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Зачем Spring?

• Облегчение работы с базами данных• Необходима интеграция с различными

сервисами в рамках тестов• IoC

Page 16: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Этапы создания тестовой платформы

Page 17: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Создание базового тестового класса

Page 18: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

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() {}}

Page 19: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Создание базовой web-страницы

Page 20: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

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) {}

}

Page 21: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Описание web-страницы

Page 22: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

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() {}

}

Page 23: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Вынесение данных в 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; }

}

Page 24: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Refactoring

• Вынесение текстовых констант из классов страниц

• Группировка DataProvider`ов в классы

Page 25: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Подключение базы данных<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.SimpleJdbcTemplate"><constructor-arg ref="dataSource"/>

</bean>

Page 26: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Работа с базой внутри DataProvider`ов

Page 27: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

@Componentpublic class SearchByAlternateNameDataProvider {

private static DataProviderGenerator dataProviderGenerator;

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

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

}

@Componentpublic class DataProviderGenerator {

@Autowiredprivate TestingJdbcTemplate testingJdbcTemplate;

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

}

Page 28: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Хинт 1 – WebDriver как SpringBean

@Configurationpublic class SeleniumConfiguration {

@Autowiredprivate WebDriver driver;

public @Bean WebDriver driver() {}

@PreDestroypublic void cleanUp() { try { driver.quit(); } catch (Throwable e) { e.printStackTrace(); } }

}

Page 29: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Хинт 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) {}

}

Page 30: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Хинт 3 – Unit-тест как тест-кейс SearchPage searchPage = loadAndLogin(); searchPage.setLegalNameSearchType(searchType); searchPage.setLegalNameSearchParam(legalName); SearchResultPage searchResultPage = searchPage.submit(); assertIsSortedByLegalName(searchResultPage);

Page 31: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Хинт 4 – Подключаем javascriptpublic 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");

}

Page 32: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Подключаем Jenkins

• Используем возможность запуска через maven

• Подключаем отчеты от TestNG и видим результаты регрессии

• Запуск тестов по расписанию / установке новой версии / …

Page 33: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Profit!

Page 34: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Куда двигаться дальше

• Создание профилей тестирования (smokem full, search)

• Selenium Grid и многопоточность• 1 подход – разные типы приложений

(WebService, ETL, ...)• End-to-end тестирование

Page 35: Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разработчиков

Андрей Ребров[email protected]

@andrebrov