Handling Exceptions in Selenium with TestNG
Why Handle Exceptions in TestNG?
When writing Selenium test scripts with TestNG, handling exceptions properly ensures that:
✔️ Tests don't fail unexpectedly.
✔️ Proper error messages are logged.
✔️ Test execution continues without stopping other test cases.
✔️ Retry mechanisms can be implemented for failed test cases.
Methods to Handle Exceptions in TestNG
1. Using Try-Catch in Test Methods
The simplest way to handle exceptions in TestNG is by using try-catch
blocks within test methods.
Example: Handling NoSuchElementException
in a TestNG Test
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class ExceptionHandlingTest {
WebDriver driver;
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
driver = new ChromeDriver();
driver.get("https://example.com");
}
@Test
public void testHandleException() {
try {
WebElement element = driver.findElement(By.id("nonexistent")); // Element may not be present
element.click();
} catch (NoSuchElementException e) {
System.out.println("Handled NoSuchElementException: " + e.getMessage());
}
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
✅ Pros: Simple, prevents test failure.
❌ Cons: Can hide real test failures if used excessively.
2. Using Expected Exceptions in TestNG (expectedExceptions
)
If you expect a specific exception in a test case, you can use TestNG's expectedExceptions
attribute to handle it automatically.
Example: Handling NoSuchElementException
with expectedExceptions
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class ExpectedExceptionTest {
WebDriver driver;
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
driver = new ChromeDriver();
driver.get("https://example.com");
}
@Test(expectedExceptions = NoSuchElementException.class)
public void testExpectedException() {
WebElement element = driver.findElement(By.id("nonexistent")); // This will throw NoSuchElementException
element.click();
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
✅ Pros: Clean and avoids unnecessary try-catch blocks.
❌ Cons: Can't log detailed error messages.
3. Using TestNG's @Listeners
for Global Exception Handling
Instead of handling exceptions in every test case, TestNG allows you to create a listener class that logs or reports exceptions globally.
Step 1: Create a Listener Class for Exception Handling
import org.testng.ITestListener;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
@Override
public void onTestFailure(ITestResult result) {
System.out.println("Test Failed: " + result.getName());
System.out.println("Reason: " + result.getThrowable().getMessage());
}
@Override
public void onTestSuccess(ITestResult result) {
System.out.println("Test Passed: " + result.getName());
}
}
Step 2: Apply Listener to the TestNG Test Class
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;
@Listeners(TestListener.class)
public class ListenerTest {
WebDriver driver;
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
driver = new ChromeDriver();
driver.get("https://example.com");
}
@Test
public void testWithListener() {
WebElement element = driver.findElement(By.id("nonexistent")); // This will trigger onTestFailure
element.click();
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
✅ Pros: Centralized exception handling, useful for reporting.
❌ Cons: Can't handle exceptions at runtime, only logs failures.
4. Using @Test
and dependsOnMethods
to Skip on Failure
If a test method depends on another method and the first one fails, TestNG will automatically skip the dependent tests.
Example: Skipping a Test if Login Fails
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class DependencyTest {
WebDriver driver;
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
driver = new ChromeDriver();
driver.get("https://example.com");
}
@Test
public void loginTest() {
try {
WebElement loginButton = driver.findElement(By.id("login")); // If not found, test fails
loginButton.click();
} catch (NoSuchElementException e) {
Assert.fail("Login button not found!");
}
}
@Test(dependsOnMethods = "loginTest")
public void dashboardTest() {
System.out.println("Dashboard Test Executed");
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
✅ Pros: Automatically skips tests if dependencies fail.
❌ Cons: If dependency is wrongly defined, unrelated tests may be skipped.
5. Using Retry Logic for Failed Tests
TestNG provides a way to automatically retry failed test cases using the IRetryAnalyzer
interface.
Step 1: Create a Retry Class
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
public class RetryFailedTests implements IRetryAnalyzer {
private int retryCount = 0;
private static final int maxRetryCount = 2; // Retry twice
@Override
public boolean retry(ITestResult result) {
if (retryCount < maxRetryCount) {
retryCount++;
return true;
}
return false;
}
}
Step 2: Apply Retry Logic to a Test
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;
public class RetryTest {
WebDriver driver;
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
driver = new ChromeDriver();
driver.get("https://example.com");
}
@Test(retryAnalyzer = RetryFailedTests.class)
public void flakyTest() {
WebElement element = driver.findElement(By.id("randomElement")); // Sometimes fails
element.click();
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
✅ Pros: Retries flaky tests, reducing false failures.
❌ Cons: Can mask real issues if overused.
Conclusion
TestNG provides multiple ways to handle exceptions in Selenium:
✔️ try-catch
for local exception handling.
✔️ expectedExceptions
for predefined exception handling.
✔️ @Listeners
for centralized failure logging.
✔️ dependsOnMethods
to skip tests if a dependency fails.
✔️ IRetryAnalyzer
to retry failed tests automatically.