In the fast-paced world of software development, automated testing plays a crucial role in ensuring the stability and reliability of applications. TestNG, a widely-used testing framework for Java applications, provides a powerful set of features that enable developers to create comprehensive test suites. However, achieving test stability and reliability can be challenging, especially when dealing with complex test scenarios. This article aims to explore how TestNG listeners can be leveraged to build robust test suites, enhancing the overall quality of automated testing.
The TestNG Framework provides us with a unique set of a annotations called @Listners. They listen to every event on the application and execute them if the event matches with the event we want to execute or want the listener to listen. These Listeners are usually before or after the test case. The most common use case of listeners in selenium testing is for generating or creating reports , taking screenshots if there is any failure in any step of execution. When the test case failure occurs, then it is redirected to the new block written for the screenshot.
Types of TestNG Listeners:
Listeners in TestNG are usually implemented with the help of interfaces. Here are the list of most commonly used interfaces to implement Listeners.
- ITestListener
- IReporter
- ISuiteListener
- IInvokedMethod
- IHookable
- IConfigurationListener
- IConfigurableListener
- IAnnotationTransformer
- IExecution
- IMethodInterceptor
ITestListener:
ITestListener is most widely used listener in Selenium WebDriver. This listener provides us with easier to implement methods using a class by overriding them. ITestListener interface has the following methods in it.
- onTestFailure(): This method gets invoked when a Test method fails.
- onTestSuccess(): This method gets invoked when a Test method succeeds.
- onTestSkipped(): This method gets invoked when we skip a Test method.
- onStart(): This method gets invoked when we just before executing any TestNG method.
- onTestFailedButWithinSuccessPercentage(): This method gets invoked when a test method fails but with a defined success percentage.
- onFinish(): This method gets invoked when all the test methods execution is done in the test class.
Implementation of ITestListener:
For Understanding of how a TestNG listener works let us create a class file with name as ExampleTests with two test cases with success and failure test cases and see how does the listeners react to these test methods.
package SampleProject.SampleProject;
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners
public class ExampleTests {
@Test
public void validateTitle() {
System.out.println("Validation of Home Page Title is Successfull");
}
@Test
public void compare() {
Assert.assertFalse(true);
}
}
For the implementation of Listeners class let us create a ListenerTestNG class file which implements the ITestListener interface.
package SampleProject.SampleProject;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class ListenerTestNG implements ITestListener {
@Override
public void onTestStart(ITestResult result) {
System.out.println("On Test Start : "+result.getName());
}
@Override
public void onTestSuccess(ITestResult result) {
System.out.println("Test cases which were successfull and its details are : "+result.getName());
}
@Override
public void onTestFailure(ITestResult result) {
System.out.println("Test cases which were Failure and its details are : "+result.getName());
}
@Override
public void onTestSkipped(ITestResult result) {
System.out.println("Test cases which have been skipped and its details are : "+result.getName());
}
@Override
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
System.out.println("Failure of test cases and its details are : "+result.getName());
}
@Override
public void onStart(ITestContext context) {
System.out.println("Test case Started");
}
@Override
public void onFinish(ITestContext context) {
System.out.println("Test case Finished");
}
}
Let us then run these test cases using a testng.xml file with listeners tag in it.
The below picture shows us how various listener methods are called based on the scenarios
Other Commonly used TestNG Interfaces:
ISuiteListener: This listener interface lets you define methods that are executed before and after the entire test suite execution. It provides methods like onStart, onFinish, onTestStart, and onTestFinish to handle suite-level events.
IInvokedMethodListener: This listener interface enables you to intercept and modify the behavior of individual test methods. It offers methods such as beforeInvocation and afterInvocation, which allow you to perform actions before and after a test method is invoked.
IAnnotationTransformer: This listener interface allows you to modify the annotations associated with test classes and methods dynamically. You can implement the transform method to change the attributes or values of the annotations at runtime.