Answer
Fixing Flaky Selenium Tests
Flaky tests are the #1 pain point in automation. They destroy trust in the test suite. Here is a systematic approach to diagnose and fix them.
Root Cause 1 — Timing / Race Conditions (Most Common)
Java
// Bad — fixed sleep
Thread.sleep(3000);
// Good — wait for specific condition
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("result")));
Root Cause 2 — Stale Element Reference
Java
// Bad — reusing stored reference across actions
WebElement btn = driver.findElement(By.id("submit"));
performIntermediateAction(); // DOM may update
btn.click(); // may be stale
// Good — find fresh before each use
performIntermediateAction();
driver.findElement(By.id("submit")).click();
Root Cause 3 — Test Data Dependency / Order
Java
// Bad — tests share state
// Test B depends on Test A creating data
// Good — each test creates its own data
@BeforeMethod
public void createTestData() {
// Create fresh user/order via API
}
@AfterMethod
public void cleanupTestData() {
// Delete test data
}
Root Cause 4 — Hardcoded Waits in Loops
Java
// FluentWait with polling handles intermittent element appearance
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofMillis(300))
.ignoring(StaleElementReferenceException.class)
.ignoring(NoSuchElementException.class);
Root Cause 5 — Environment Differences
- ✓Use
WebDriverManagerto auto-match browser/driver versions - ✓Pin browser versions in CI Docker image
- ✓Use relative file paths, not absolute
- ✓Externalize environment URLs via properties/env vars
Retry Failed Tests (Short-Term Fix)
In testng.xml:
XML
<suite name="Regression" verbose="1">
<test name="Tests" preserve-order="true">
<parameter name="retryCount" value="2"/>
</test>
</suite>
Java
public class RetryAnalyzer implements IRetryAnalyzer {
private int count = 0;
private static final int MAX_RETRY = 2;
@Override
public boolean retry(ITestResult result) {
return count++ < MAX_RETRY;
}
}
// On test
@Test(retryAnalyzer = RetryAnalyzer.class)
public void myTest() { ... }
Flakiness Investigation Checklist
| Symptom | Likely Cause |
|---|---|
| Fails on first run, passes on retry | Timing / race condition |
| Fails only in CI, passes locally | Environment / headless issue |
| Fails randomly, no pattern | Stale element or shared state |
| Fails after another test | Test order dependency |
| Fails on slow machines | Insufficient wait timeouts |
