There appears to be a dilemma, a problem, that I see quite often on the selenium mailing lists and forum boards. To sum things up, they usually read-"help! my tests are giving me errors...sometimes". But why? Why are your tests erroneous and why sometimes? After all, tests that give false results aren't worth their weight in bytes. I scroll down and look for any clues, an explanation, a traceback, or even better...a code snippet. Aha! Some code.
comment_button = webdriver.find_element_by_css_selector("#comment")
comment_textfield = webdriver.find_element_by_css_selector("#comment input[type='text']")
comment_textfield.clear()
comment_textfield.send_keys("Testing a comment")
comment_button.click()
comment_text = webdriver.find_element_by_css_selector("#comment .text")
assertEqual("Testing a comment", comment_text.text)
Hmm. That looks right. Grab a handle on the button, the textfield, and the text. Submit a comment and after that, assert that the text is equal. So what's wrong with this test?
Well the answer is not as obvious as we might think. But it's as simple as waiting. You see, Webdriver is great at driving browsers but it has no idea on when to stop. It keeps on going unless you tell it to...relax. So when you drive the page and click on something or do anything AJAXey, this creates a race condition between your page's JavaScript and Webdriver test. Thus, your tests will pass or fail...sometimes. Let's just hope, for your test's sake, that Javascript is the first to the finish line, every time.
Ok I've had enough. I want my tests to pass. All the time. Let's tell Webdriver to wait.
A solution: time.sleep()
import time
.
comment_button.click()
time.sleep(2)
comment_text = webdriver.find_element_by_css_selector("#comment .text")
Awesome! My test passes. But now I'm explicitly waiting 2 seconds. Is this good? Well, yes and no. On one hand, my tests will probably always pass because now every time the test click's on a comment button, JavaScript has a 2 second lead to finish updating the DOM and making the comment text visible. On the other hand, that's 2 seconds and spread among hundreds of tests...well you get the picture. There has got to be something better than telling Webdriver to stop for an arbitrary period of time.
A better solution: webdriver.implicitly_wait
webdriver.implicitly_wait(2)
.
.
Success! 'implicitly_wait', when called, will set a timeout for a certain period of time and will throw an error if the element is not found. One of the advantages of this approach is that you only have to set the wait once during the Webdriver instance lifetime. But can we get better?
The best solution: WebdriverWait
from selenium.webdriver.support.ui import WebdriverWait
.
comment_button.click()
WebdriverWait(webdriver, 2).until(lambda x:
x.find_element_by_css_selector("#comment .text"))
comment_text =
webdriver.find_element_by_css_selector("#comment .text")
.
Great Success! WebdriverWait will wait for a specified time and will perform the callback at a default of .5 seconds. The poll frequency can be set by passing in a poll_frequency keyword arg when initializing the WebdriverWait object. Another advantage over implicitly_wait is that you aren't blanketing every attempt to locate an object. Rather, you are explicitly using wait when you need to.
Well it's as simple as that. Knowing when to wait. Remember, a good test is one that tests correctly and provides accurate results...all the time.
Comments
11.15.2011
Great, I had a code example of WebdriverWait in Java side, you can click here to see how it works in Java :-):
11.15.2011
Great, I had a code example of WebdriverWait in Java side, you can click here to see how it works in Java :-):
11.22.2011
Great example, WebDriverWait is one of the most valuable features of Sel2/WebDriver.
I have an example in java, for pre and post v2.6. You can check it out here if you're interested: http://automatingsoftwaretesting.wordpress.com/2011/09/17/why-webdriverw...
11.22.2011
Thanks for the Java example!
11.29.2011
Where's the C# example?
12.05.2011
right here:
12.05.2011
http://seleniumhq.org/docs/04_webdriver_advanced.html#explicit-waits
12.05.2011
Luke, thanks for the C Sharp info.
03.29.2012
Where to post feedback to you?
Online Classifieds