Should we use a WebDriverWait, or an assertion?
I watched some of your lectures and webinars and it looks like you are using WebDriverWait partly as a substitute for assertions. Is that normal?
WebDriverWait will throw an exception if it can’t find the item. Which has a similar effect to an Assert i.e the
@Test will fail. I do not view this as an assert, I view this as setting up the necessary preconditions for the test, rather than a specific ‘check’ that the
I explicitly use Asserts when the Assert describes something important for the test. So when people read the test they know what I am ‘testing for’.
Sometimes I add an Assert after a
WebDriverWait, even though I know the Assert will never be thrown if the
WebDriverWait fails, because in the context of the code, the Assert documents something important for the test.
I do not create tests without Asserts in production, even if a wait could act as an Assert.
Upon review I’d consider the test unclear, and I’d have to add a comment saying “no assert because the wait will fail”. Also it would mean a reliance on abstraction layers or Waits, but the system may change over time and the abstractions and necessary Waits may also change. But since I encode the test rationale in the Asserts, if all the Asserts become irrelevant and we remove them, then we also remove the need for the @Test itself.
Also I don’t add asserts to my abstraction layers, but I do add WebDriverWaits.
Semantically they differ, even if the end result of using them might seem the same.
And sometimes, when I’m creating example code, I might stop at the
WebDriverWait because it is ‘good enough’ for the demo. But I’d have to think carefully before considering it ‘good enough’ for production code.
Given this setup code:
driver.get("https://testpages.herokuapp.com/styled/index.html"); WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.elementToBeClickable( By.id("htmlformtest"))); driver.findElement(By.id("htmlformtest")).click();
If I wanted to check I was on the right page before continuing then I would use a
wait.until(ExpectedConditions.titleIs("HTML Form Elements"));
If I wanted to assert that the title was correct then I could use the above wait, but I’d prefer to see:
Assertions.assertEquals("HTML Form Elements", driver.getTitle());
And I’d try to synchronise on something else in the test, e.g. is the footer correct or is the page state ready in some other way.
If the wait was the only way of synchronising the page, but the assertion was what was important. Then I might write a comment explaining this.
String pageTitle = "HTML Form Elements"; wait.until(ExpectedConditions.titleIs(pageTitle)); // wait will already have failed, but the condition // we are testing for is the page title Assertions.assertEquals(pageTitle, driver.getTitle());
Note: I put the expected page title text into a String, to reduce maintenance and make sure the assert was never out of date for the condition we are testing.
It is highly likely that the redundant Assertion would eventually be removed in a code review as having ‘code’ which is documentation, is probably too risky long term.
The full source for this is in my Webdriver Java FAQs project:
If you want to learn how to use Selenium WebDriver with Java then check out our online courses.