Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 9 лет назад пользователемЗахар Лутошин
1 Бодрящий микс из Selenium и TestNG Регрессионное тестирование руками разработчиков Ребров Андрей Luxoft
2 @andrebrov
3 Сколько тестировщиков в вашей команде?
7 Всегда кажется, что их не хватает
8 При этом... «У нас agile» - значит, тестирование должно завершиться в том же спринте «Люблю короткие релизы»- значит регрессионное тестирование надо делать постоянно «Они опять изменили требования!» - значит опять надо менять тесты
9 Хватит это терпеть!
10 Задачи Нужно иметь возможность проводить регрессию в короткий период времени Тесты должны быть простыми, чтобы их можно было легко написать/дописать/переписать Поддержка тестов не должна занимать много времени
11 Необходимые инструменты Тестовый фреймворк Фреймворк функционального тестирования CI Server + удобная IDE, понятный генератор отчетов, удобный язык программирования...
12 Что взяли мы TestNG Selenium 2 / WebDriver Spring IntelliJ IDEA Jenkins Набор самописных утилит
13 Почему TestNG Удобная работа с данными Разбиение тестов по группам Многопоточность «из коробки» «Фабрика» тестов
14 Почему WebDriver Java-фреймворк Абстракция на уровне PageObject Работа с IE & FF Активно развивается
15 Зачем Spring? Облегчение работы с базами данных Необходима интеграция с различными сервисами в рамках тестов IoC
16 Этапы создания тестовой платформы
17 Создание базового тестового класса public abstract class AbstractSeleniumTestClass extends AbstractTestNGSpringContextTests private WebDriver = true) public void printTestName(Method method) { = true) public void clearCookies(Method method) throws Exception { } protected WebDriver getWebDriver() { } public SearchPage loadLemAndLogin() { }
18 Создание базовой web- страницы public abstract class AbstractPage extends LoadableComponent { 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) { }
19 Описание web-страницы dfpublic class LoginPage extends AbstractPage { private static final Logger log = = private WebElement = private WebElement = private WebElement loginButton; public LoginPage(WebDriver driver) { super(driver); protected By getPageLoadedCheckElementLocator() { protected void isLoaded() throws Error { } public SearchPage login() { }
20 Вынесение данных в DataProvider public class SearchDataProvider 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; }
21 Refactoring Вынесение текстовых констант из классов страниц Группировка DataProvider`ов в классы
22 Подключение базы данных
23 Работа с базой внутри public class SearchByAlternateNameDataProvider { private static DataProviderGenerator public void setDataProviderGenerator(DataProviderGenerator dataProviderGenerator) { SearchByAlternateNameDataProvider.dataProviderGenerator = dataProviderGenerator; public static Object[][] alternateNameAndNonSuitableCOI() { return dataProviderGenerator.generatePairStringString("select … + Config.DATA_COUNT); public class DataProviderGenerator private TestingJdbcTemplate testingJdbcTemplate; public Object[][] generatePairStringString(String sql) { List list = testingJdbcTemplate.getSimpleJdbcTemplate().query(sql, new PairRowMapper()); Object[][] result = new Object[list.size()][2]; int i = 0; for (Pair pair : list) { result[i][0] = pair.getOne().toString(); result[i++][1] = pair.getTwo().toString(); } return result; }
24 Хинт 1 – WebDriver как public class SeleniumConfiguration private WebDriver driver; WebDriver driver() { public void cleanUp() { try { driver.quit(); } catch (Throwable e) { e.printStackTrace(); }
25 Хинт 2 – TestFactory для похожих тестов public class SearchTestFactory = "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; = "legalNamesAndCountries", dataProviderClass = = SRC-19") public void test(String param1, String param2) { }
26 Хинт 3 – Unit-тест как тест-кейс SearchPage searchPage = loadAndLogin(); searchPage.setLegalNameSearchType(searchType); searchPage.setLegalNameSearchParam(legalName); SearchResultPage searchResultPage = searchPage.submit(); assertIsSortedByLegalName(searchResultPage);
27 Хинт 4 – Подключаем javascript public void waitForAjaxComplete() { log.verbose("waiting for ajax completion"); wait.until(new ExpectedCondition () { public Boolean apply(WebDriver driver) { return (Boolean) js.executeScript("return $.active == 0"); } }); log.verbose("All ajax calls are complete"); }
28 Подключаем Jenkins Используем возможность запуска через maven Подключаем отчеты от TestNG и видим результаты регрессии Запуск тестов по расписанию / установке новой версии / …
29 Profit!
30 Куда двигаться дальше Создание профилей тестирования (smokem full, search) Selenium Grid и многопоточность 1 подход – разные типы приложений (WebService, ETL,...) End-to-end тестирование
31 Андрей
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.