Upload
igor-khrol
View
21.403
Download
5
Embed Size (px)
DESCRIPTION
My speech on SeleniumCamp'2013
Citation preview
Типичные ошибки начинающих писать тесты на WebDriver
Игорь Хрол
О себе
• Игорь Хрол• Более шести лет в
автоматизации тестирования• Тренер, консультант, инженер,
менеджер, архитектор• Selenium, HP QTP, TestCompete,
Jmeter• Докладчик на
SeleniumCamp’2011 и 2012
О чём будем говорить?
Мы все когда-то начинали– Подводные камни Selenium’a– Ошибки в программировании
Основано на личном мироощущении
Selenium 2.0 (WebDriver) API
• Selenium – это библиотека для работы с браузером
• Требуются знания и усердие, чтобы сделать из неё автоматические тесты
Проверки
Только текстовый вывод и ничего больше…
//Some actionsif (isElementPresent(By.id("identifier"))) {
log("PASS: Element was on the page");} else {
log("FAIL: Element wasn't shown");}//Some other actions
Проверки
Использование готового решения
@Testpublic void testImportantFeature() {
//Some actionsAssert.assertTrue(isElementPresent(By.id("identifier")),
"Element wasn't shown");log("PASS: Element was on the page");//Some other actions
}
isElementPresent
• NoSuchElementException вместо false, если элемента нет на странице
• Возвращает false, если элемент есть на странице, но невидимый
public boolean isElementPresent(By locator) { return driver.findElement(locator).isDisplayed();}
isElementPresent
Если возвращает false, то «подвисает» на таймаут, указанный в implicitlyWait
public boolean isElementPresent(By locator) { try { driver.findElement(locator); return true; } catch(NoSuchElementException e) { return false; }}
isElementPresent
Ненужная исключительная ситуация
public boolean isElementPresent(By locator) {try {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
driver.findElement(locator);return true;
} catch(NoSuchElementException e) {return false;
} finally {driver.manage().timeouts().
implicitlyWait(30, TimeUnit.SECONDS);}
}
isElementPresent
Ну и если совсем-совсем хочется…
public boolean isElementPresent(By locator) {driver.manage().timeouts().
implicitlyWait(0, TimeUnit.SECONDS);boolean result = driver.
findElements(locator).size() > 0;driver.manage().timeouts().
implicitlyWait(30, TimeUnit.SECONDS);return result;
}
isElementPresentpublic boolean isElementPresent(By locator) {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
List<WebElement> list = driver.findElements(locator);driver.manage().timeouts().
implicitlyWait(30, TimeUnit.SECONDS);if (list.size() == 0) {
return false;} else {
return list.get(0).isDisplayed();}
}
WebDriver API не возвращает Null
Ничего не проверяет…
WebElement element = driver.findElement(By.id("identifier"));
Assert.assertNotNull(element, "Element wasn't found");
Alert alert = driver.switchTo().alert();Assert.assertNotNull(alert, "Alert wasn't found");
try-catch где попало
• Получаете NullPointerException вместо NoSuchElementException
• Исключительные ситуации используются для «падения» тестов
public WebElement getElement(By locator) {try {
return driver.findElement(locator);} catch (NoSuchElementException e) {
return null;}
}
Сгеренированный XPath
• Используйте «характерные» свойства элементов:
//table[@id=‘dataTable’]• Выучите XPath
/html/body/div[4]/div/div/div/table/tbody/tr[2]/td[2]/div/table/tbody/tr/td[2]/div/a
Хорошо:• //a[text()=‘Link’]• //div[@id=‘container’]• //table[@name=‘named’]
Плохо:• //a[@text=‘Link’]• //a[@text()=‘Link’]
XPath: text() – это функция
"sleep" для синхронизации
• Не решает проблем синхронизации• Сильно увеличивает время выполнения
тестов
Включайте его, он хороший
• Если вы вызываете метод findElement, скорее всего вы хотите его найти
• Если не можем найти, то лучше немного подождать
implicitlyWaitdriver.manage().timeouts().
implicitlyWait(30, TimeUnit.SECONDS);
Лишняя логика в скриптах
• Тест-скрипты линейные по своей природе• Чем больше логики в скриптах, тем
больше шанс допустить ошибку
public void click(By locator) {if (isElementPresent(locator)) {
driver.findElement(locator).click();}
}
Собственные циклы для синхронизации
public void waitForSomething() {int timeout = 30000;long start = System.currentTimeMillis();while (System.currentTimeMillis() - start < timeout) {
if (isSomething()) {return;
} else {try {
Thread.sleep(1000);} catch (InterruptedException e1) {}
};}Assert.assertFalse(true,
"Timeout is over waiting for something");}
Собственные циклы для синхронизации
public void waitForSomething() {WebDriverWait waiter =
new WebDriverWait(driver, 30, 1000);waiter.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver input) {return isSomething(input);
}});
}
XPath vs CSS
“CSS работает быстрее XPath”
• Было актуально только для Selenium RC и Internet Explorer
• Уже неактуально
Сравнение скорости на Internet Explorer 9.0 + Selenium 2.29.0
XPath CSS
//*[@id='g-search-input'] #g-search-input
56 45
//form[@id='globalSearch']//input form#globalSearch input
40 30
//header[@class='g-top']//form[@id='globalSearch']//input
header.g-top form#globalSearch input
40 20
Время в миллисекундах
• Да, CSS быстрее• Но оба метода работают приемлемо быстро
Ошибки в программированииАвтоматизация тестирования – это программирование и разработка
программного обеспечения
Лучше начать с изучения языка
Названия переменных и методов
• Подумайте о ваших последователях• IDE позволяют эффективно
переименовывать
int spanNumber =driver.findElements(By.tagName("div")).size();
System.out.println("Number of div: " + spanNumber);
public int multiply(int x, int y) {return x / y;
}
Закомментированный код
Система контроля версий хранит все ваши изменения!/*public boolean isElementPresent(By locator) {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);boolean result = driver.findElements(locator).size() > 0;driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);return result;
} */
public boolean isElementPresent(By locator) {driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);List<WebElement> list = driver.findElements(locator);driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);if (list.size() > 0) {
return true;} else {
return list.get(0).isDisplayed();}
}
Непонятные комментарии
Пишите так, чтобы вы сами могли понять написанное через несколько месяцев
private boolean someMethod() {// Errorreturn false;
}
Используйте конвенции языка, на котором пишете
• Java:– Классы с большой буквы– Методы с маленькой буквы– Объекты и переменные с маленькой буквы– Camel-нотация
• С#– Классы с большой буквы– Методы с большой буквы– Объекты и переменные с маленькой буквы– Camel-нотация
warning
Держите код в «чистом» состоянии
Итого
Делать ошибки – это часть развития!Давайте учиться программировать
качественно!
Спасибо за внимание!
Игорь Хрол• E-mail: [email protected] • Skype: igor.khrol • LinkedIn: http://www.linkedin.com/in/khroliz • Блог: http://ru.khroliz.com • Facebook: https://www.facebook.com/khroliz