Using Explicit Waits in Selenium to Improve Test Case Reliability

Selenium test cases can be a pain to write. They seem to fail for inane and irreplicable reasons that vanish on the next run of the test case. However, incorporating Explicit Waits can help reduce the number of false failures you receive.

I use Selenium at work to run test cases that are called by Nagios checks. Since Nagios needs a response from a check within 60s, having predictable wait times is imperative. Rather than using the implicit waits for everything, I prefer to set explicit waits depending on what it is that I'm waiting on.

The default value in Selenium for an implicit wait is 0 seconds. This means that running driver.find_element_by_id("main-box") will fail if the element isn't there, even if the page hasn't fully loaded yet.

I solve this by using WebDriverWait and expected_conditions.

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

# [...] (code ommitted)

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "application")),
                                "Page did not load as expected")

This code calls WebDriverWait on the driver I set up, it waits a maximum of 10s or until the expected condition (EC) is met. If the EC is not met, then it will raise a TimeoutException with "Page did not load as expected" as the error message.

Not only does WebDriverWait allow me to explicitly set how long to wait for something (e.g. the presence of an element on a page), but it also allows me to set the error message to something meaningful that will help our on-shift team identify where the issue actually is – all without having to add an unnecessary try-catch block.

Explicitly specifying how long I want to wait for an element to load or until a page's title changes allows me to better guarantee that a site is actually broken when our test cases fail – not that it just happened to load slower than expected.

Note: code examples are in Python, but the same functionality is available in Java and other Selenium libraries.