What are TestNG Listeners?
TestNG Listeners are used to modify the default behavior of TestNG. They are interfaces that allow us to perform actions before, after, or during the execution of test methods, suites, classes, etc.
Listeners are notified when a specific event occurs, like:
A test starts
A test passes or fails
A test gets skipped
A suite starts or ends
Test class starts or ends
Types of TestNG Listeners
| Listener Interface | Description |
|---|---|
| ITestListener | Listens to test case execution (success, failure, skip, start, finish) |
| ISuiteListener | Listens to the start and end of a test suite |
| IClassListener | Listens to before and after test class events |
| IInvokedMethodListener | Listens before and after every method (including @BeforeMethod, @Test, @AfterMethod) |
| IAnnotationTransformer | Modifies annotations (@Test, @Before, etc.) at runtime |
| IReporter | Used to generate custom reports |
| ITestNGListener | Marker interface – superinterface for all listeners |
1.
ITestListener ExamplePurpose:
Tracks test result lifecycle: start, success, failure, skipped.
Java code:
import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; public class MyTestListener implements ITestListener { public void onTestStart(ITestResult result) { System.out.println("Test Started: " + result.getName()); } public void onTestSuccess(ITestResult result) { System.out.println("Test Passed: " + result.getName()); } public void onTestFailure(ITestResult result) { System.out.println("Test Failed: " + result.getName()); } public void onTestSkipped(ITestResult result) { System.out.println("Test Skipped: " + result.getName()); } public void onStart(ITestContext context) { System.out.println("Test Suite Started: " + context.getName()); } public void onFinish(ITestContext context) { System.out.println("Test Suite Finished: " + context.getName()); } }
Test Class:
import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @Listeners(MyTestListener.class) public class SampleTest { @Test public void test1() { Assert.assertTrue(true); } @Test public void test2() { Assert.assertTrue(false); } @Test(dependsOnMethods = "test2") public void test3() { System.out.println("This test depends on test2"); } }
2.
ISuiteListener ExamplePurpose:
Tracks start and end of the entire test suite.
Java code:
import org.testng.ISuite; import org.testng.ISuiteListener; public class MySuiteListener implements ISuiteListener { public void onStart(ISuite suite) { System.out.println("Suite Started: " + suite.getName()); } public void onFinish(ISuite suite) { System.out.println("Suite Finished: " + suite.getName()); } }
testng.xml
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite"> <listeners> <listener class-name="MySuiteListener"/> </listeners> <test name="Test"> <classes> <class name="SampleTest"/> </classes> </test> </suite>
3.
IInvokedMethodListener ExamplePurpose:
Triggers before and after every method including setup and teardown.
Java code:
import org.testng.IInvokedMethod; import org.testng.IInvokedMethodListener; import org.testng.ITestResult; public class MyMethodListener implements IInvokedMethodListener { public void beforeInvocation(IInvokedMethod method, ITestResult result) { System.out.println("Before method: " + method.getTestMethod().getMethodName()); } public void afterInvocation(IInvokedMethod method, ITestResult result) { System.out.println("After method: " + method.getTestMethod().getMethodName()); } }
4.
IAnnotationTransformer ExamplePurpose:
Modify test annotations at runtime. Useful for enabling/disabling tests programmatically.
Java code:
import org.testng.IAnnotationTransformer; import org.testng.annotations.ITestAnnotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class MyAnnotationTransformer implements IAnnotationTransformer { public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { annotation.setEnabled(true); // Force all tests to be enabled } }
5.
IReporter ExamplePurpose:
Used for generating custom reports after execution.
Java code:
import org.testng.*; import java.util.List; import java.util.Map; public class MyReporter implements IReporter { public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) { for (ISuite suite : suites) { System.out.println("Suite Name: " + suite.getName()); Map<String, ISuiteResult> suiteResults = suite.getResults(); for (ISuiteResult result : suiteResults.values()) { ITestContext context = result.getTestContext(); System.out.println("Passed tests: " + context.getPassedTests().getAllResults().size()); System.out.println("Failed tests: " + context.getFailedTests().getAllResults().size()); } } } }
How to Use Listeners
- Using
@ListenersAnnotation in your test class:
@Listeners({MyTestListener.class, MyMethodListener.class}) public class SampleTest { ... }
- Using
testng.xmlfile:
<listeners> <listener class-name="MyTestListener"/> <listener class-name="MySuiteListener"/> <listener class-name="MyReporter"/> </listeners>