Типичные ошибки начинающих писать тесты на WebDriver

47,461 views

Published on

My speech on SeleniumCamp'2013

Published in: Education
0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
47,461
On SlideShare
0
From Embeds
0
Number of Embeds
24,349
Actions
Shares
0
Downloads
148
Comments
0
Likes
14
Embeds 0
No embeds

No notes for slide

Типичные ошибки начинающих писать тесты на WebDriver

  1. 1. Типичные ошибки начинающих писать тесты на WebDriver Игорь Хрол
  2. 2. О себе• Игорь Хрол• Более шести лет в автоматизации тестирования• Тренер, консультант, инженер, менеджер, архитектор• Selenium, HP QTP, TestCompete, Jmeter• Докладчик на SeleniumCamp’2011 и 2012
  3. 3. О чём будем говорить?Мы все когда-то начинали – Подводные камни Selenium’a – Ошибки в программированииОсновано на личноммироощущении
  4. 4. Selenium 2.0 (WebDriver) API• Selenium – это библиотека для работы с браузером• Требуются знания и усердие, чтобы сделать из неё автоматические тесты
  5. 5. Проверки //Some actions if (isElementPresent(By.id("identifier"))) { log("PASS: Element was on the page"); } else { log("FAIL: Element wasnt shown"); } //Some other actionsТолько текстовый вывод и ничегобольше…
  6. 6. Проверки@Testpublic void testImportantFeature() { //Some actions Assert.assertTrue(isElementPresent(By.id("identifier")), "Element wasnt shown"); log("PASS: Element was on the page"); //Some other actions} Использование готового решения
  7. 7. isElementPresentpublic boolean isElementPresent(By locator) { return driver.findElement(locator).isDisplayed();}• NoSuchElementException вместо false, если элемента нет на странице• Возвращает false, если элемент есть на странице, но невидимый
  8. 8. isElementPresent public boolean isElementPresent(By locator) { try { driver.findElement(locator); return true; } catch(NoSuchElementException e) { return false; } }Если возвращает false, то «подвисает» натаймаут, указанный в implicitlyWait
  9. 9. isElementPresentpublic 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); }}Ненужная исключительная ситуация
  10. 10. isElementPresentpublic 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;}Ну и если совсем-совсем хочется…
  11. 11. 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(); }}
  12. 12. WebDriver API не возвращает NullWebElement element = driver.findElement(By.id("identifier"));Assert.assertNotNull(element, "Element wasnt found");Alert alert = driver.switchTo().alert();Assert.assertNotNull(alert, "Alert wasnt found");Ничего не проверяет…
  13. 13. try-catch где попалоpublic WebElement getElement(By locator) { try { return driver.findElement(locator); } catch (NoSuchElementException e) { return null; }}• Получаете NullPointerException вместо NoSuchElementException• Исключительные ситуации используются для «падения» тестов
  14. 14. Сгеренированный XPath/html/body/div[4]/div/div/div/table/tbody/tr[2]/td[2]/div/table/tbody/tr/td[2]/div/a• Используйте «характерные» свойства элементов://table[@id=‘dataTable’]• Выучите XPath
  15. 15. XPath: text() – это функцияХорошо:• //a[text()=‘Link’]• //div[@id=‘container’]• //table[@name=‘named’]Плохо:• //a[@text=‘Link’]• //a[@text()=‘Link’]
  16. 16. "sleep" для синхронизации• Не решает проблем синхронизации• Сильно увеличивает время выполнения тестов
  17. 17. implicitlyWait driver.manage().timeouts(). implicitlyWait(30, TimeUnit.SECONDS);Включайте его, он хороший• Если вы вызываете метод findElement, скорее всего вы хотите его найти• Если не можем найти, то лучше немного подождать
  18. 18. Лишняя логика в скриптах public void click(By locator) { if (isElementPresent(locator)) { driver.findElement(locator).click(); } }• Тест-скрипты линейные по своей природе• Чем больше логики в скриптах, тем больше шанс допустить ошибку
  19. 19. Собственные циклы для синхронизации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");}
  20. 20. Собственные циклы для синхронизацииpublic void waitForSomething() { WebDriverWait waiter = new WebDriverWait(driver, 30, 1000); waiter.until(new Predicate<WebDriver>() { public boolean apply(WebDriver input) { return isSomething(input); } });}
  21. 21. XPath vs CSS“CSS работает быстрее XPath”• Было актуально только для Selenium RC и Internet Explorer• Уже неактуально
  22. 22. Сравнение скорости на 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] header.g-top form#globalSearch input //form[@id=globalSearch]//input 40 20 Время в миллисекундах• Да, CSS быстрее• Но оба метода работают приемлемо быстро
  23. 23. Ошибки в программировании Автоматизация тестирования – это программирование и разработка программного обеспечения
  24. 24. Лучше начать с изучения языка
  25. 25. Названия переменных и методов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;}• Подумайте о ваших последователях• IDE позволяют эффективно переименовывать
  26. 26. Закомментированный кодСистема контроля версий хранит все вашиизменения!/*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(); }}
  27. 27. Непонятные комментарии private boolean someMethod() { // Error return false; }Пишите так, чтобы вы сами могли понятьнаписанное через несколько месяцев
  28. 28. Используйте конвенции языка, на котором пишете• Java: – Классы с большой буквы – Методы с маленькой буквы – Объекты и переменные с маленькой буквы – Camel-нотация• С# – Классы с большой буквы – Методы с большой буквы – Объекты и переменные с маленькой буквы – Camel-нотация
  29. 29. warningДержите код в «чистом» состоянии
  30. 30. ИтогоДелать ошибки – это часть развития! Давайте учиться программировать качественно!
  31. 31. Спасибо за внимание!Игорь Хрол• E-mail: khroliz@gmail.com• Skype: igor.khrol• LinkedIn: http://www.linkedin.com/in/khroliz• Блог: http://ru.khroliz.com• Facebook: https://www.facebook.com/khroliz

×