There are different interfaces provided by Java that allows you to modify TestNG behaviour. These interfaces are further known as TestNG Listeners in . TestNG Listeners also allows you to customize the tests logs or report according to your project requirements. TestNG Listeners in Selenium WebDriver are modules that listens to certain events and keep track of test execution while performing some action at every stage of test execution. Selenium WebDriver This is a TestNG tutorial, where I will help you realize the different TestNG listeners with examples so you could use them proficiently the next time you plan to work with TestNG and Selenium. TestNG Listeners in Selenium WebDriver can be implemented at two levels: Class level: In this, you implement listeners for each particular class no matter how much test cases it includes. Suite level: In this, you implement listeners for a particular suite which includes several classes as test cases. Types of TestNG Listeners In Selenium WebDriver There are numerous TestNG listeners in Selenium WebDriver, some of them are used very frequently by the testing community & some are almost forgotten. In this TestNG tutorial, I will demonstrate the most popular TestNG listeners with examples but before that, let me enlist the various TestNG listeners in Selenium WebDriver. ITestListener IAnnotationTransformer IInvokedMethodListener ISuiteListener IReporter IConfigurable IExecutionListener IHookable IMethodInterceptor IConfigurationListener Frequently Used TestNG Listeners With Examples Now, in this TestNG tutorial, let’s us first look into the most popular & widely used TestNG listeners with examples. 1. ITestListener ITestListener is the most adopted TestNG listener in Selenium WebDriver. Providing you with an easy to implement interface through a normal Java class, where the class overrides every method declared inside the ITestListener. By using this TestNG listener in Selenium WebDriver, you can change the default behaviour of your test by adding different events to the methods. It also defines a new way of logging or reporting. Following are some methods provided by this interface: : This method is invoked before any test method gets executed. This can be used to get the directory from where the tests are running. onStart : This method is invoked after all tests methods gets executed. This can be used to store information of all the tests that were run. onFinish : This method is invoked before any tests method is invoked. This can be used to indicate that the particular test method has been started. onTestStart : This method is invoked when each test method is skipped. This can be used to indicate that the particular test method has been skipped. onTestSkipped : This method is invoked when any test method gets succeeded. This can be used to indicate that the particular test method has successfully finished its execution. onTestSuccess : This method is invoked when any test method gets failed. This can be used to indicate that the particular test method has been failed. You can create an event of taking a screenshot which would show where the test has been failed. onTestFailure : This method is invoked each time the test method fails but is within the success percentage mentioned. To implement this method, we use two attributes as a parameter of test annotation in TestNG i.e. successPercentage and invocationCount. The success percentage takes the value of success percentage and invocation count denotes the number of times that a particular test method would execute. onTestFailedButWithinSuccessPercentage : @Test(successPercentage=60, invocationCount=5), in this annotation success percentage is 60% and invocation count is 5, that means out of 5 times if at least 3 times ((⅗)*100= 60) the test method gets passed, it would be considered as passed. For example For every ITestListener method we usually pass the following arguments: 1. interface along with its instance “result” which describes the result of a test. “ITestResult” Note: If you want to trace your exception through ITestResult then you need to avoid try/catch handling. 2. interface along with its instance “context” which describes the test context containing all the information of the given test run. “ITestContext” Now, in this TestNG tutorial for listeners, we will take a basic example code for running the test at the class level. Logs would get generated at a console and it would help you understanding which tests passed, failed and skipped. The first class(ListentersBlog.java) would contain all the methods implemented by ITestListener interface: package TestNgListeners; org.testng.ITestContext; org.testng.ITestListener; org.testng.ITestResult; public { public onTestStart(ITestResult result) { System.out.println( +result.getName()); } public onTestSuccess(ITestResult result) { System.out.println( +result.getName()); } public onTestFailure(ITestResult result) { System.out.println( +result.getName()); } public onTestSkipped(ITestResult result) { System.out.println( +result.getName()); } public onTestFailedButWithinSuccessPercentage(ITestResult result) { System.out.println( +result.getName()); } public onStart(ITestContext context) { System.out.println( +context.getOutputDirectory()); } public onFinish(ITestContext context) { System.out.println( +context.getPassedTests()); System.out.println( +context.getFailedTests()); } } import import import class ListenersBlog implements ITestListener void "New Test Started" void "Test Successfully Finished" void "Test Failed" void "Test Skipped" void "Test Failed but within success percentage" void "This is onStart method" void "This is onFinish method" "This is onFinish method" Below is the code that includes the tests methods(TestNGListenersTest.java). Make sure you add a Listeners annotation just above your class name to implement the above added methods. Syntax: @Listeners(PackageName.ClassName.class) package TestNgListeners; org.openqa.selenium.By; org.openqa.selenium.WebDriver; org.openqa.selenium.chrome.ChromeDriver; org.testng.SkipException; org.testng.annotations.Listeners; org.testng.annotations.Test; junit.framework.Assert; @Listeners(TestNgListeners.ListenersBlog.class) public { @Test public sampleTest1() throws InterruptedException { System.setProperty( , ); WebDriver driver = ChromeDriver(); driver.get( ); driver.manage().window().maximize(); driver.findElement(By.xpath( )).click(); Thread.sleep( ); driver.findElement(By.cssSelector( )).click(); Thread.sleep( ); driver.findElement(By.linkText( )).click(); Thread.sleep( ); driver.quit(); } @Test public sampleTest2() throws InterruptedException { System.out.println( ); Assert.assertTrue( ); } private int i = ; @Test(successPercentage = , invocationCount = ) public sampleTest3() { i++; System.out.println( + i); (i == || i == ) { System.out.println( ); Assert.assertEquals(i, ); } } @Test public sampleTest4() { SkipException( ); } } import import import import import import import class TestNGListenersTest //Passing Test void "webdriver.chrome.driver" "C:\\Users\\Lenovo-I7\\Desktop\\Selenium\\chromedriver.exe" new "https://www.apple.com/" "//*[@id=\'ac-globalnav\']/div/ul[2]/li[3]" 2000 "#chapternav &gt; div &gt; ul &gt; li.chapternav-item.chapternav-item-ipad-air &gt; a" 2000 "Why iPad" 2000 //Failing Test void "Forcely Failed Test Method" false 0 60 5 //Test Failing But Within Success Percentage void "Test Failed But Within Success Percentage Test Method, invocation count: " if 1 2 "sampleTest3 Failed" 6 //Skipping Test void throw new "Forcely skipping the sampleTest4" Console Output Screen: Now, suppose you have multiple classes in your project, then adding TestNG Listeners in Selenium WebDriver to each class might be a pain. In such cases, you can create a test suite and add Listeners tag to your suite(xml file) instead of adding Listeners to each class. Here is the example code(testng.xml) for running the test at the suite level: <?xml version= encoding= ?> <suite name="TestNG Listeners Suite" parallel="false"> <listeners> <listener class-name="TestNgListeners.ListenersBlog" /> </listeners> <test name="Test"> <classes> <class name="TestNgListeners.TestNGListenersTest" /> </classes> </test> </suite> "1.0" "UTF-8" <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> 2. IAnnotationTransformer IAnnotationTransformer is an interface that provides a method “transform” which would get invoked by TestNG to modify the behaviour of Test annotation method in our test class. The transform method provides various parameters: : The annotation that would get read from the test class. annotation : If the annotation found on a class, this parameter would represent that same class. testClass : If the annotation found on a constructor, this parameter would represent that same constructor. testConstructor : If the annotation found on a method, this parameter would represent that same method. testMethod : At least one of the parameters will be non-null. Note Below is the sample code that would be executed at the suite level. In this code, we have used a parameter “alwaysRun = true” in our Test annotation that indicates that the test method would always run even if the parameters on which the method depends fails. However, we would transform this behaviour of our test method through IAnnotationTransformer Listener which won’t allow the particular test method to get executed. Listeners Class File: package TestNgListeners; java.lang.reflect.Constructor; java.lang.reflect.Method; org.testng.IAnnotationTransformer; org.testng.annotations.ITestAnnotation; public { public boolean isTestRunning(ITestAnnotation ins) { (ins.getAlwaysRun()) { ; } ; } public transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { (isTestRunning(annotation)) { annotation.setEnabled( ); } } } import import import import class AnnotationTransformers implements IAnnotationTransformer if return true return false void if false Test Class File: package TestNgListeners; org.testng.annotations.Listeners; org.testng.annotations.Test; public { @Test(alwaysRun= ) public test1() { System.out.println( ); } @Test public test2() { System.out.println( ); } } import import class AnnotationTransformerTests true void "This is my first test whose behaviour would get changed while executing" void "This is my second test executing" Console Output Screen: This interface allows you to perform some action before and after a method has been executed. This listener gets invoked for configuration and test methods. This TestNG listener in Selenium WebDriver works same as the ITestListerner and the ISuiteListerner. However, there is a difference that you should make a note of & that is, in IInvokedMethodListener, it makes the call before and after every method. 3. IInvokedMethodListener There are two methods to be implemented: beforeInvocation(): This method is invoked prior every method. afterInvocation(): This method is invoked post every method. Here is sample code for this listener, implemented at class level. InvokedMethodListeners.java(includes listeners implemented methods) package TestNgListeners; org.testng.IInvokedMethod; org.testng.IInvokedMethodListener; org.testng.ITestResult; public { public beforeInvocation(IInvokedMethod method, ITestResult testResult) { System.out.println( + method.getTestMethod().getMethodName() + + testResult.getTestClass()); } public afterInvocation(IInvokedMethod method, ITestResult testResult) { System.out.println( + method.getTestMethod().getMethodName() + + testResult.getTestClass()); } } import import import class InvokedMethodListeners implements IInvokedMethodListener void "Before Invocation of: " "of Class:" void "After Invocation of: " "of Class:" File Name: InvokedMethodListenersTest.java (includes configuration and test methods) package TestNgListeners; org.testng.annotations.AfterClass; org.testng.annotations.BeforeClass; org.testng.annotations.Listeners; org.testng.annotations.Test; @Listeners(value=InvokedMethodListeners.class) public { @Test public test1() { System.out.println( ); } @Test public test2() { System.out.println( ); } @BeforeClass public setUp() { System.out.println( ); } @AfterClass public cleanUp() { System.out.println( ); } } import import import import class InvokedMethodListenersTest void "My first test" void "My second test" void "Before Class method" void "After Class method" Console Output Screen: 4. ISuiteListener This TestNG listener in Selenium WebDriver is implemented at a suite level called ISuiteListener. It has 2 methods: : This method is invoked prior the test suite execution. onStart : This method is invoked post the test suite execution. onFinish This listener basically listen to the events to have occurred before and after the execution of the suite.If the parent suite further contains child suites then child suites are executed before running the parent suite. : Implementing ISuiteListener with normal java class and adding the unimplemented methods. Step 1 Class: SuiteListeners package TestNgListeners; org.testng.ISuite; org.testng.ISuiteListener; public { public onStart(ISuite suite) { System.out.println( + suite.getName()); } public onFinish(ISuite suite) { System.out.println( + suite.getName()); } } import import class SuiteListeners implements ISuiteListener void "Suite executed onStart" void "Suite executed onFinish" : Creating two test classes to be added in two different child suites. Step 2 Class 1: SuiteListenersTests1 package TestNgListeners; org.testng.annotations.AfterSuite; org.testng.annotations.BeforeSuite; org.testng.annotations.Test; public { @BeforeSuite public test1() { System.out.println( ); } @Test public test2() { System.out.println( ); } @AfterSuite public test3() { System.out.println( ); } } import import import class SuiteListenersTests1 void "BeforeSuite method in Suite1" void "Main Test method 1" void "AfterSuite method in Suite1" Class 2: SuiteListenersTests2 package TestNgListeners; org.testng.annotations.AfterSuite; org.testng.annotations.BeforeSuite; org.testng.annotations.Test; public { @BeforeSuite public test1() { System.out.println( ); } @Test public test2() { System.out.println( ); } @AfterSuite public test3() { System.out.println( ); } } import import import class SuiteListenersTests2 void "BeforeSuite method in Suite2" void "Main Test method 2" void "AfterSuite method in Suite2" Step 3: Adding the test classes to the child suites. Suite 1: Test Suite One.xml <?xml version= encoding= ?> <suite name="Test Suite One"> <test name="Test Method1"> <classes> <class name="TestNgListeners.SuiteListenersTests1"/> </classes> </test> </suite> "1.0" "UTF-8" <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> Suite 2: Test Suite Two.xml <?xml version= encoding= ?> <suite name="Test Suite Two"> <test name="Test Method2"> <classes> <class name="TestNgListeners.SuiteListenersTests2"/> </classes> </test> </suite> "1.0" "UTF-8" <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> : Creating a parent suite xml file that would combine other 2 defined suites along with the listeners class. Step 4 <?xml version= encoding= ?> <suite name="suiteListener"> <listeners> <listener class-name="TestNgListeners.SuiteListeners"></listener> </listeners> <suite-files> <suite-file path="./Suite1.xml"> </suite-file> <suite-file path="./Suite2.xml"> </suite-file> </suite-files> </suite> "1.0" "UTF-8" <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> Console Output Screen: 5. IReporter This TestNG listener in Selenium WebDriver provides an interface which helps you to customize the test report generated by TestNG. It provides generateReport method which would get invoked after execution of all the suites. The method further contains three parameters: : it provides you with a list of multiple suites presented in the testng xml file that goes under execution. xmlSuite : This object represents a great deal of information about the classes, packages, test execution result, along with all the test methods. Basically, it represents detailed information around the suite after the final execution. suites : contains the output folder path where the report gets generated. outputDirectory Below is the example of IReporterer listener at suite level. File Name :ReporterListener.java package TestNgListener; java.util.List; java.util.Map; org.testng.IReporter; org.testng.ISuite; org.testng.ISuiteResult; org.testng.ITestContext; org.testng.xml.XmlSuite; public { public generateReport(List xmlSuites, List suites, outputDirectory) { (ISuite isuite : suites) { &lt;string, isuiteresult= &gt; suiteResults = isuite.getResults(); sn = isuite.getName(); (ISuiteResult obj : suiteResults.values()) { ITestContext tc = obj.getTestContext(); System.out.println( + sn + + tc.getPassedTests().getAllResults().size()); System.out.println( + sn + + tc.getFailedTests().getAllResults().size()); System.out.println( + sn + + tc.getSkippedTests().getAllResults().size()); } } } } &lt; import import import import import import import class ReporterListener implements IReporter void String for Map "" String for "Passed Tests of" "=" "Failed Tests of" "=" "Skipped Tests of" "=" /string,&gt; File Name: ReporterTest.java package TestNgListener; org.testng.SkipException; org.testng.annotations.Listeners; org.testng.annotations.Test; junit.framework.Assert; public { @Test public FirstTest() { System.out.println( ); Assert.assertTrue( ); } @Test public SecondTest() { System.out.println( ); Assert.fail( ); } @Test public ThirdTest() { System.out.println( ); SkipException( ); } } import import import import class ReporterTest void "The First Test Method" true void "The Second Test Method" "Failing this test case" void "The Third Test Method" throw new "Test Skipped" Console Output Screen: Not So Frequently Used TestNG Listeners In Selenium WebDriver In this section, I will be highlighting those TestNG listeners which are not so renowned as the ones discussed in the previous section. I have avoided the practical demonstration of these TestNG listeners with their examples as they are rarely used. I will, however, help you understand their purpose. 6. IConfigurationListener This TestNG listener in Selenium WebDriver is used to create an event only when the configuration method is passed, failed or skipped. Below are the unimplemented methods provided by this listener: : It gets invoked when the configuration method gets succeeded. onConfigurationSuccess : It gets invoked when the configuration method gets failed. onConfigurationFailure : As the name suggests, when your configuration method is skipped, it calls for onConfigurationSkip method. onConfigurationSkip 7. IExecutionListener This listener is used to keep track when the test or suite run start and finish. It provides two methods: : It is invoked before the suite or test starts running. onExecutionStart : It is invoked after the suite or test gets executed. onExecutionFinish Note: It is not possible for this listener to prevent the execution but only to create events in some way. Also, you can provide more than one “IExecution” listener as you configure TestNG. This interface skips the invocation of test methods and provides a run method which gets invoked instead of each @Test method found. The test method is then invoked once the callBack() method of the IHookCallBack parameter is called. 8. IHookable IHookable listener is utilized when you wish to perform testing on classes which require JAAS authentication. This can be used to set permissions i.e. for whom the test method should run and when the test method should get skipped. → To return the list of IMethodInstance, post-execution of TestNG. 9. IMethodInterceptor → To sort the list of test methods. TestNG would execute the tests methods in the same order defined in the returned value. IMethodInterceptor interface includes only one method to implement “intercept” which returns the modified list of test methods. : One of the test methods SampleTestOne is to test the logs, so we grouped it in “LogCheck”. Example Now, suppose we only want to run the LogCheck grouped tests and not the other tests, so, we have to provide an IMethodInterceptor listener that can eliminate the other tests and return only LogCheck grouped tests. The ICongurable listener is somewhat similar to IHookable listener. This interface skips the invocation of test methods and provides a run method which gets invoked instead of each configuration method found. The configuration method is then invoked once the callBack() method of the IConfigureCallBack parameter is called. 10. IConfigurable Which TestNG Listeners In Selenium WebDriver Do You Use The Most? I hope this TestNG tutorial, helped you to realize which TestNG listeners are most suitable for your project requirements. Regarding the rarely used TestNG listeners, if there are any specific TestNG listener in that you find highly useful then feel free to share them in the comment section below. Also, if you have any questions related to the article, let me know. I look forward to your replies. Happy testing! 🙂 Selenium Previously published at https://www.lambdatest.com/blog/testng-listeners-in-selenium-webdriver-with-examples/