TestNg Listener in Selenium Java

What is Listeners ?

TestNg listeners are the interfaces that allows us to modify the TestNg behavior. TestNg listeners allows us to customize logs or reports of TestNg. These listeners listen the TestNg events and behave accordingly. we can modify the logs of the reports as per our requirements.In this tutorial we will learn how to use these listeners in our projects.

Types of Listeners in TestNg ?

Below are the several types of listeners in TestNg . In this tutorial we will learn about the ITestListener.

1) IAnnotationTransformer
2) IAnnotationTransformer2
3) IHookable
4) IInvokedMethodListener
5) IMethodInterceptor
6) IReporter
7) ISuiteListener
8) ITestListener


Different ways to implement TestNg listeners ?

There are two ways to implement the TestNg Listners

1) Extend the TestListnersAdapter
2) Implement the interface “ITestListener” and implement all its method.

We can implement these listeners at class level and suite level. When we have multiple classes using listeners in that case we define the listeners at suite level.


How to implement TestNg listeners in live Project ?

Implement ITestListener at Class Level

ITestListener is an interface we just need to implement the interface , as in Java if we implement interface we need to define all its method or we make the class abstract if we do not define all methods.
Here we will implement all its method by aover the mouse on class name “TestNg_Listeners” and click on “Add unimplemented methods” .

TestNg Listeners

Below methods of ITestListener  interface

1) onTestStart – This method will invoke when any test case started.
2) onTestSuccess – This method will invoke when any test cases is passed
3) onTestFailure -This method will invoke when any test cases fail and it can be used to take screen shot when any test case fails.
4) onTestSkipped – This method will invoke when any test cases is skipped.
5) onTestFailedButWithinSuccessPercentage
6) onStart – This method will invoke once before executing test cases of a class.
7) onFinish – This method will invoke once all test cases executed of a class.

There is a parameter “ItestResult “. ItestResult class describes the result of a test.. This will behave depends on Test case is passed or not and store the test result in object “Result”(you can name it accordingly) . Just observe the below program to see the functionality.

Create TestNg_Listeners class which implements the TestNg listeners

package com.listeners;

import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

public class TestNg_Listeners implements ITestListener {

 // ItestResult will behave whether the test case passed or not
 // and store the value in result object
 
 // it will execute when the any test case start
 @Override
 public void onTestStart(ITestResult result) {
 
 System.out.println("------------------------");
 System.out.println("-----onTestStart function called----------------");
 System.out.println("Test Case started and test case name is " + result.getName());
 }

 // it will execute when the any test case pass
 @Override
 public void onTestSuccess(ITestResult result) {
 
 System.out.println("-----onTestSuccess function called----------------");
 System.out.println("Test Case passed and test case name is " + result.getName());
 }

 // it will execute when the any test case fails
 @Override
 public void onTestFailure(ITestResult result) {
 
 System.out.println("-----onTestFailure function called----------------");
 System.out.println("Test Case fails and test case name is " + result.getName());
 }

 // it will execute when the any test case skipped
 @Override
 public void onTestSkipped(ITestResult result) {
 
 System.out.println("-----onTestSkipped function called----------------");
 System.out.println("Test Case skipped and test case name is " + result.getName());
 }

 // it will execute when the any test case fails but with some success percentage
 @Override
 public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
 
 System.out.println("------------------------");
 System.out.println("---Test cases success percentage----" + result.getName());
 System.out.println("------------------------");
 }

 // it will execute when the test case starts of particular class
 @Override
 public void onStart(ITestContext context) {
 
 System.out.println("--------onStart function called----------------");
 System.out.println("---Test cases executions started----" + context.getName());
 System.out.println("--------onStart function end----------------");
 }

 // it will execute when all test case finish of particular class
 @Override
 public void onFinish(ITestContext context) {
 
 System.out.println("------------------------");
 System.out.println("------onFinish function called------------------");
 System.out.println("---Test cases execution finished ----" + context.getName());
 System.out.println("------onFinish function end------------------");
 
 }

 
}

Create “TestCase_Listeners” class and define 3 test cases – Test Case 1 will pass , Test case 2 will fail and Test case 3 will skip to understand the listeners in more clear way.

Implement ITestListener at Class Level with @Listeners annotation

package com.listeners;

import org.testng.Assert;
import org.testng.SkipException;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

// implemented at class level with annotation
@Listeners(com.listeners.TestNg_Listeners.class)
public class TestCase_Listeners {

 
 // Test case 1 is passed
 @Test
 public void TestCase1Pass()
 {
 String actual_status = "pass";
 String expected_status = "pass";
 Assert.assertEquals(actual_status, expected_status); 
 }
 
 @Test
 public void TestCase2Fail()
 {
 String actual_status = "pass";
 String expected_status = "fail";
 Assert.assertEquals(actual_status, expected_status); 
 }
 
 @Test
 public void TestCase3Skipped()
 {
 throw new SkipException("Test Case is Skipped");
 
 }
}

Note : @Listeners(com.listeners.TestNg_Listeners.class) annotation defined at the class level which consist of package name and class name.

Output of the above program and observe it 

onstart function called first before executing all other test cases and onfinish called at last when all test executed of the class.

--------onStart function called----------------
---Test cases executions started----Default test
--------onStart function end----------------
------------------------
-----onTestStart function called----------------
Test Case started and test case name is TestCase1Pass
-----onTestSuccess function called----------------
Test Case passed and test case name is TestCase1Pass
------------------------
-----onTestStart function called----------------
Test Case started and test case name is TestCase2Fail
-----onTestFailure function called----------------
Test Case fails and test case name is TestCase2Fail
------------------------
-----onTestStart function called----------------
Test Case started and test case name is TestCase3Skipped
-----onTestSkipped function called----------------
Test Case skipped and test case name is TestCase3Skipped
------------------------
------onFinish function called------------------
---Test cases execution finished ----Default test
------onFinish function end------------------

===============================================
    Default test
    Tests run: 3, Failures: 1, Skips: 1
===============================================

Implement Listeners at Suite level

Now suppose we have n number of classes in such case we have to define the annotation @Listeners on all the classes that is too hectic. To overcome that we can define the listeners at Suite level which can be used by all test cases of any class.

XML file to implement listeners at suite level – add below code to xml file and remove annotation from the class now.

<listeners>
<listener class-name=”com.listeners.TestNg_Listeners”></listener>
</listeners>

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name="com.listeners.TestNg_Listeners"></listener>
</listeners>
  <test name="Test">
    <classes>
      <class name="com.listeners.TestCase_Listeners"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

ITestListener Class without annotation and TestNg_Listener class is same

package com.listeners;

import org.testng.Assert;
import org.testng.SkipException;
import org.testng.annotations.Test;


public class TestCase_Listeners {

	
	// Test case 1 is passed
	@Test
	public void TestCase1Pass()
	{
		String actual_status = "pass";
		String expected_status = "pass";
		Assert.assertEquals(actual_status, expected_status);		
	}
	
	@Test
	public void TestCase2Fail()
	{
		String actual_status = "pass";
		String expected_status = "fail";
		Assert.assertEquals(actual_status, expected_status);		
	}
	
	@Test
	public void TestCase3Skipped()
	{
		throw new SkipException("Test Case is Skipped");
		
	}
}

Note : Output is same as above and when we define the listeners at suite level it will be used by all the test cases defined within suite.

This is all abou the TestNg listeners in selenium and how to use the listeners in selenium. It covers all the concept from the selenium interview point of view also.