Reliable & Maintainable Webdriver Tests
public void canShareOnTwitter() {
SocialVideo ad = createSocialVideo();
ad.shareBar.twitterShareIcon.click();
assertTrue(
urlOfNewWindow()
.contains("twitter.com")
);
}
- Failure message
- Stacktrace
- Browser Request Logs
- Screenshots
- JS Console Output
class AdditionalDiagnostics
extends RuntimeException {
public AdditionalDiagnostics(
Browser browser, Throwable e) {
super(
e.getMessage() +
consoleLog(browser) +
httpRequests(browser),
screenshots(browser),
e
);
}
}
waitUntil(
tweetIcon::isDisplayed
);
/* ... */
brandBar.click();
assertTrue( /* from */
brandBar.isVisible()
);
waitUntilTrue( /* to */
brandBar::isVisible
);
default void waitUntil(
Supplier<Boolean> condition,
int timeout) {
new WebDriverWait(driver, timeout, 50)
.until((WebDriver driver) ->
condition.get()
);
}
"our tests are flaky again"
@ReliabilityCheck(
runs=1000
)
Treat Tests like Monitoring
"You're breaking our site!"
@Test
public void shouldSeeErrorIfPasswordIncorrect() {
User publisherWithInvalidPassword
= new PublisherWithInvalidPassword();
Page page =
when(publisherWithInvalidPassword.using(browser, url))
.attemptsTo(loginAs(publisherWithInvalidPassword))
.enact();
then(publisherWithInvalidPassword.using(browser, page))
.should(haveIncorrectCredentialsMessage())
.check();
}
.attemptsTo(loginAs(publisher))
.attemptsTo(navigateToEarnings())
.attemptsTo(viewSavedReport())
/* extract, reuse */
.attemptsTo(viewEarnings())
Opportunities
- UI itself is valuable
- Many Browsers
- Invariants (Sound)
- Reuse for monitoring
Maintainability
- Page-Object Pattern
- Screenplay Pattern
- Refactor Ruthlessly
Performance
- Synchronous
- Delete Tests
- Monitor Instead
- Stub Dependencies
- Parallelise
Reliability
- Subcutaneous Tests
- @Quarantine
- Discipline
- Diagnostics
- Wait for Interactivity
- Wait; don't Assert
- Fix the Implementation
- Stub Dependencies
- Treat like Monitoring
- Stress Test