Бодрящий микс из Selenium и TestNG Регрессионное тестирование руками разработчиков
Ребров Андрей
Luxoft
Презентация на тему Презентация на тему Бодрящий микс из Selenium и TestNG Регрессионное тестирование руками разработчиков, предмет презентации: Разное. Этот материал содержит 31 слайдов. Красочные слайды и илюстрации помогут Вам заинтересовать свою аудиторию. Для просмотра воспользуйтесь проигрывателем, если материал оказался полезным для Вас - поделитесь им с друзьями с помощью социальных кнопок и добавьте наш сайт презентаций ThePresentation.ru в закладки!
Бодрящий микс из Selenium и TestNG Регрессионное тестирование руками разработчиков
Ребров Андрей
Luxoft
При этом...
«У нас agile» - значит, тестирование должно завершиться в том же спринте
«Люблю короткие релизы»- значит регрессионное тестирование надо делать постоянно
«Они опять изменили требования!» - значит опять надо менять тесты
Задачи
Нужно иметь возможность проводить регрессию в короткий период времени
Тесты должны быть простыми, чтобы их можно было легко написать/дописать/переписать
Поддержка тестов не должна занимать много времени
Необходимые инструменты
Тестовый фреймворк
Фреймворк функционального тестирования
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
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-страницы
dfpublic 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;
public LoginPage(WebDriver driver) {
super(driver);
}
@Override
protected By getPageLoadedCheckElementLocator() {
}
@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`ов в классы
Работа с базой внутри 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) {
List
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;
}
}
Хинт 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
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 тестирование
Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:
Email: Нажмите что бы посмотреть