We have already discussed WebDriver Listeners. In that tutorial, we discussed all the fundamental concepts of the listeners. Just to remind you, Listeners listen to the events on starting of the tests, finishing the tests, when tests failed, passed or skipped, hence, if you implement listeners in your Selenium project then you do not need to write separate logs for all these basic operations. Listeners will automatically capture it as the log and send data to the console. Today we are going to discuss TestNG listener which is called as ITestListener.
TestNG is fully equipped with all the advanced features which any tester needs so the TestNG listener is one of them. Before we jump to the agenda of this tutorial, I would like to recommend you a tutorial on WebDriver Even Listener. You should read it as it will add another milestone to your knowledge bank.
What is TestNG Listener?
TestNG listener formally called as ITestListener, which is an interface in TestNG. A normal Java class implements ITestListener and overrides all the methods written inside it. Each method corresponds to an event of your Selenium Project.
ITestListener effectively helps in creating a new way of logging. We can implement log4j logging along with the implementation of ITestListener.
How to set up TestNG Listener through ITestListener?
At first, we need to implement ITestListener then we override the methods written inside it. Here are the methods which will be overridden.
package Test; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; public class ListenersDefinitionClass implements ITestListener{ public void onTestStart(ITestResult result) { // TODO Auto-generated method stub } public void onTestSuccess(ITestResult result) { // TODO Auto-generated method stub } public void onTestFailure(ITestResult result) { // TODO Auto-generated method stub } public void onTestSkipped(ITestResult result) { // TODO Auto-generated method stub } public void onTestFailedButWithinSuccessPercentage(ITestResult result) { // TODO Auto-generated method stub } public void onStart(ITestContext context) { // TODO Auto-generated method stub } public void onFinish(ITestContext context) { // TODO Auto-generated method stub } }
We will discuss two techniques to call TestNG listener in the Selenium project. Here are them:
Technique# 1: Through @Listeners annotation
We add @Listeners annotation in the TestNG class in which we want logging through listeners. Hence, we add the annotation before the class definition.
@Listeners(package.ITestListenerImplementedClass.class)
Technique# 2: Through testng.xml file
If we want TestNG listener to be implemented to the entire Selenium project, then we need to define it in the testng.xml file. Here is the statement:
<listeners> <listener class-name="Test.ListenersDefinitionClass"></listener> </listeners>
Steps to implement TestNG Listener using ITestListener
We saw an overview of the implementation of ITestListener. Let’s see the step by step implementation in the project.
Step# 1: Implement ITestListener in Java Class
Here is the implementation of ITestListener. We override the methods which are written inside it.
package Test; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; public class ListenersDefinitionClass implements ITestListener{ public void onTestStart(ITestResult result) { System.out.println("Test started- "+result.getName()); } public void onTestSuccess(ITestResult result) { System.out.println("Test completed successfully- "+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 onTestFailedButWithinSuccessPercentage(ITestResult result) { // TODO Auto-generated method stub } public void onStart(ITestContext context) { System.out.println("Started- "+context.getName()); } public void onFinish(ITestContext context) { System.out.println("Finished- "+context.getName()); } }
Step# 2: Implementation of Listener by using @Listeners annotation
Here we will keep testng.xml file normally implemented whereas we implement the listener in a specific class file by using @Listeners annotation.
package Test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.Assert; import org.testng.SkipException; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @Listeners(ListenersDefinitionClass.class) public class TestngListeners { WebDriver driver; @BeforeClass public void setUp(){ System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe"); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://www.inviul.com/"); driver.manage().window().maximize(); } @AfterClass public void tearDown(){ driver.close(); driver.quit(); } @Test(priority=1) public void getTitle() { System.out.println("Title is- "+driver.getTitle()); } @Test(priority=2) public void skipTest() { throw new SkipException("This test skipped- "+this.getClass().getSimpleName()); } @Test(priority=3) public void failTest() { Assert.assertEquals(driver.getTitle(), "Test"); } }
testng.xml file
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite"> <test thread-count="2" name="Test" > <classes> <class name="Test.TestngListeners"/> </classes> </test> <!-- Test --> </suite> <!-- Suite -->
Alternative Step# 2: Implementation of Listener at project level through the testng.xml file
Here we remove @Listeners annotation and we define one general implementation of the listener in the testng.xml file. So here is the implementation.
package Test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.Assert; import org.testng.SkipException; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Listeners; import org.testng.annotations.Test; public class TestngListeners { WebDriver driver; @BeforeClass public void setUp(){ System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe"); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://www.inviul.com/"); driver.manage().window().maximize(); } @AfterClass public void tearDown(){ driver.close(); driver.quit(); } @Test(priority=1) public void getTitle() { System.out.println("Title is- "+driver.getTitle()); } @Test(priority=2) public void skipTest() { throw new SkipException("This test skipped- "+this.getClass().getSimpleName()); } @Test(priority=3) public void failTest() { Assert.assertEquals(driver.getTitle(), "Test"); } }
testng.xml file
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite"> <listeners> <listener class-name="Test.ListenersDefinitionClass"></listener> </listeners> <test thread-count="2" name="Test" > <classes> <class name="Test.TestngListeners"/> </classes> </test> <!-- Test --> </suite> <!-- Suite -->
Console Output
Below screenshot is the console output. The same output will come in both the techniques.
This is all about TestNG Listener using ITestListener. You can write your queries below and don’t forget to join our Facebook group for more updates on Selenium.
Hi Avi, Now able to understand the logic between the ListenerDefinition and TestngLister Class. How it is printing all as mentioned from the definition class. I am so very confused here.
Listener definition means the implementation of all the methods written inside ITestListner interface, whereas, TestNG Listener is just a way to say listeners provided by TestNG. This is something you don’t need to bother about.
If you have any questions with code and implementation, please let me know.
Hello Avinash,
Kindly check my code below. After importing ITestListener, I can’t add the unimplemented methods in the Listeners, because Listeners class is not exposing the interface methods of the ITestListener.
Thanks.
package TestNg;
import org.testng.ITestListener;
public class Listeners implements ITestListener {
}
It should warn to add unimplemented methods.
Are you using Intellij IDE?