Best Practices
Principles to keep your Selenium test suite reliable and maintainable.
Best practices checklist
text
✅ Always use explicit waits — never Thread.sleep()
✅ Use Page Object Model (POM) to separate locators from test logic
✅ Run headless in CI (ChromeOptions --headless)
✅ Prefer CSS selectors over XPath (faster, more readable)
✅ Use data-testid attributes in your app for stable locators
✅ Take screenshots on test failure (attach to TestNG/JUnit reports)
✅ One assertion per test for clarity
✅ Clean up (quit driver) even when tests fail — use @AfterMethod
✅ Parametrize tests with DataProvider or @ParameterizedTest
✅ Avoid hardcoded waits; use ExpectedConditions
✅ Keep test data out of test code — use config files or factories
✅ Run tests in parallel with TestNG parallel="methods"Screenshot on failure (TestNG listener)
java
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.io.File;
import org.apache.commons.io.FileUtils;
public class ScreenshotListener implements ITestListener {
@Override
public void onTestFailure(ITestResult result) {
Object obj = result.getInstance();
if (obj instanceof BaseTest test) {
try {
File src = ((TakesScreenshot) test.driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("screenshots/" + result.getName() + ".png"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}