Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

The Waiting Game: How to Design Reliable Selenium Tests by Corina Pip

234 Aufrufe

Veröffentlicht am

The biggest issue when it comes to Selenium tests is attempting to interact with the page elements when they are not ready. Trying to click an element before it is available, trying to select a value from a dropdown when it is not yet populated, checking an element attribute before it is available – these are some of the most common reasons for failures when it comes to Selenium tests. Such issues can be avoided by using the WebDriverWait Java class to redesign the way you interact with your page. In this SauceCon 2018 talk, Corina Pip will show you how to get from click to click and wait, from select a dropdown value to wait and select, and so on. She will show you how to replace your standard Selenium commands, like click, with customized waits that you can write to adapt to your test environment conditions. Corina will show you how to rethink your page interactions from a waiting perspective. And, as an added bonus, how you can replace some of the assertions you write with corresponding wait methods.

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

The Waiting Game: How to Design Reliable Selenium Tests by Corina Pip

  1. 1. THE WAITING GAME. HOW TO DESIGN RELIABLE SELENIUM TESTS Corina Pip @imalittletester https://iamalittletester.wordpress.com https://git.io/v56wB
  2. 2. • Twitter: @imalittletester • Blog: https://iamalittletester.wordpress.com/ • Travel blog: https://travelwithcori.wordpress.com/ • Photos: https://www.flickr.com/photos/capreoara • GitHub: https://github.com/iamalittletester/learning-project @imalittletester https://iamalittletester.wordpress.com/
  3. 3. Most common Selenium test issue •Timing •Page not ready when interacting with it •Invalid failures •Retry, retry…retry @imalittletester https://iamalittletester.wordpress.com/
  4. 4. BUT FIRST OF ALL! •Understand how the software you test behaves •No wait method will work if you do not understand how the software works @imalittletester https://iamalittletester.wordpress.com/
  5. 5. Introducing WebDriverWait @imalittletester https://iamalittletester.wordpress.com/ WebDriverWait wait = new WebDriverWait(driver, timeout); wait.until(arg0 -> ExpectedCondition);
  6. 6. Introducing WebDriverWait - How does it work? •Wait for up to timeout •Check for condition every half a second •If condition is fulfilled before timeout  carry on with rest of the test •If condition is not fulfilled before timeout  throw Exception @imalittletester https://iamalittletester.wordpress.com/
  7. 7. Benefits of using waits •Tests have higher chance of passing •When they are supposed to pass (no bugs in software under test) •More confidence in tests •No need for hard waits (no sleeps!) @imalittletester https://iamalittletester.wordpress.com/
  8. 8. What can we wait for? Almost EVERYTHING @imalittletester https://iamalittletester.wordpress.com/
  9. 9. What can we wait for? URLs To equal To contain To start with To not contain To not equal All above ignore case MISC Page load Dropdown to be populated Element attribute To equal To contain To not contain All above ignore case Element To be visible To be clickable To be checked Element text To equal To contain To not equal To not contain To start with All above ignore case @imalittletester https://iamalittletester.wordpress.com/
  10. 10. Design considerations •Have dedicated Waiter class •Holds all wait methods •Defines the TIMEOUT constant •Tests do not need to specify it •Unless they want to override the value @imalittletester https://iamalittletester.wordpress.com/
  11. 11. Bonus: using Waits instead of assertions •Previously: •Perform some actions that trigger a visual change •Sleep so that you “wait” for the visual change •Assert the visual change •Now: •Perform some actions + wait for the visual change @imalittletester https://iamalittletester.wordpress.com/
  12. 12. Example – wait for element attribute equals String public void waitForElementAttributeToEqualString( WebElement element, String attribute, String expectedString, WebDriver driver, int timeout) { WebDriverWait wait = new WebDriverWait(driver, timeout); wait.until(arg0 -> element.getAttribute(attribute).equals(expectedString)); } @imalittletester https://iamalittletester.wordpress.com/
  13. 13. Opening a page, and waiting for it to load • Classic approach: driver.get(URL); BAD! Thread.sleep(5000); • Refinement v.1: driver.get(URL); BETTER waiter.waitForPageLoadComplete(driver); 2 lines of code @imalittletester https://iamalittletester.wordpress.com/
  14. 14. Opening a page, and waiting for it to load @imalittletester https://iamalittletester.wordpress.com/ Who is waitForPageLoadComplete? public void waitForPageLoadComplete(WebDriver driver) { Wait<WebDriver> wait = new WebDriverWait(driver,TIMEOUT); wait.until(driver1 -> String .valueOf(((JavascriptExecutor) driver1) .executeScript("return document.readyState")) .equals("complete")); }
  15. 15. Opening a page, and waiting for it to load • Refinement v.2: waiter.get(URL, driver); BEST! • Who is this get? public void get(String url, WebDriver driver) { driver.get(url); waitForPageLoadComplete(driver); } @imalittletester https://iamalittletester.wordpress.com/
  16. 16. The “invisible redirect syndrome” •Example: •Fill in a form •Click the submit button •The submit triggers some URL redirects •Clicking the button takes you through a few other URLS before the success page •Click a button on the success page @imalittletester https://iamalittletester.wordpress.com/
  17. 17. The “invisible redirect syndrome” •Classic approach: performSomeActions; button.click(); Thread.sleep(5000); moreActions; @imalittletester https://iamalittletester.wordpress.com/
  18. 18. The “invisible redirect syndrome” •BAD approach: performSomeActions; button.click(); waiter.waitForPageLoadComplete(); moreActions; clicks on wrong page @imalittletester https://iamalittletester.wordpress.com/
  19. 19. The “invisible redirect syndrome” •Good approach v1.0: performSomeActions; button.click(); waiter.waitForURL(); moreActions; @imalittletester https://iamalittletester.wordpress.com/
  20. 20. The “invisible redirect syndrome” @imalittletester https://iamalittletester.wordpress.com/ • Who is this waitForURL? WebDriverWait wait = new WebDriverWait(driver, TIMEOUT); ExpectedCondition<Boolean> urlIsCorrect = arg0 -> driver.getCurrentUrl().equals(url); wait.until(urlIsCorrect); waitForPageLoadComplete(driver, TIMEOUT);
  21. 21. The “but the element is there” syndrome • Element interaction throws exception StaleElementReferenceException InvalidElementStateException ElementNotVisibleException ElementNotSelectableException NoSuchElementException • “But the element is there” – you can see it  wait for it to become available @imalittletester https://iamalittletester.wordpress.com/
  22. 22. Click public void click(WebElement element, WebDriver driver, int timeout) { WebDriverWait wait = new WebDriverWait(driver, timeout); ExpectedCondition<Boolean> elementIsClickable = arg0 -> { try { element.click(); return true; } catch (Exception e) { return false; } }; wait.until(elementIsClickable); } @imalittletester https://iamalittletester.wordpress.com/
  23. 23. Click-and-wait •Click actions trigger UI events •New elements to be displayed •Elements to be removed •Page refresh (same URL) •New page loaded (new URL) •WebElement attributes to change values •WebElement text to change … @imalittletester https://iamalittletester.wordpress.com/
  24. 24. Click-and-wait • Example: button.click(); Thread.sleep(); assertEquals(element.getText(), expectedString); • Enhancement v1.0: button.click(); 2 lines waiter.waitForElementTextEquals(expectedString); of code @imalittletester https://iamalittletester.wordpress.com/
  25. 25. Click-and-wait • Who is this waitForElementTextEquals? WebDriverWait wait = new WebDriverWait(driver, timeout); ExpectedCondition<Boolean> elementTextEqualsString = arg0 -> element.getText().equals(expectedString); wait.until(elementTextEqualsString); @imalittletester https://iamalittletester.wordpress.com/
  26. 26. Click-and-wait • Enhancement v2.0: waiter.clickAndwaitForElementTextEquals( buttonToClick, element, expectedString); • Who is this method? waiter.click() + waiter.waitForElementTextEquals() @imalittletester https://iamalittletester.wordpress.com/
  27. 27. Click-and-wait – revisiting the redirect issue • Good approach v1.0: performSomeActions; button.click(); waiter.waitForURL(); moreActions; • Good approach v2.0: performSomeActions; waiter.clickAndwaitForURL(); moreActions; @imalittletester https://iamalittletester.wordpress.com/
  28. 28. Click-and-wait driver.get(url1); Thread.sleep(5000); assertTrue(element1.isDisplayed() ); element1.click(); Thread.sleep(5000); assertTrue(element2.isDisplayed() ); driver.get(url1); Thread.sleep(5000); assertTrue(element1.isDisplayed()); element1.click(); Thread.sleep(5000); assertTrue(element2.isDisplayed()); @imalittletester https://iamalittletester.wordpress.com/
  29. 29. Click-and-wait driver.get(url1); Thread.sleep(5000); element1.click(); Thread.sleep(5000); assertTrue( element2.isDisplayed()); getUrlAndWaitForElementDisplayed(url1, element1); clickAndWaitForElementDisplayed(element1, element2); @imalittletester https://iamalittletester.wordpress.com/
  30. 30. A bugger – selecting from a “stale” dropdown @imalittletester https://iamalittletester.wordpress.com/ WebDriverWait wait = new WebDriverWait(driver, TIMEOUT); ExpectedCondition elementSelectedFromDropdown = (ExpectedCondition<Boolean>) arg0 -> { String selectedValue = ""; try { Select select = new Select(selectRoot); select.selectByValue(value); … return selectedValue.equals(value); } catch (StaleElementReferenceException f) { return false; }}; wait.until(elementSelectedFromDropdown);
  31. 31. From driver. and element. to waiter. •Instead of using driver methods, use waiter methods: •driver.get  waiter.getAnd… •element.click  waiter.clickAnd… @imalittletester https://iamalittletester.wordpress.com/
  32. 32. THANK YOU For details, check out: https://github.com/iamalittletester/thewaiter ALSO: @imalittletester https://iamalittletester.wordpress.com/