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.