TestNG Overview
TestNG stands for ‘Test Next Generation’. It is a popular test automation framework that enables you to create easily-to-read code scripts and generate customized test reports. They initially designed TestNG to perform unit testing. Lately, they extended TestNG to cover all types of testing, including integration system testing and unit testing. Cedric Beust designed the tool in 2003, taking inspiration from JUnit and NUnit. With powerful features such as annotations, TestNG listeners, data providers, etc. incorporated into the tool, TestNG is now more popular and easy to use compared to JUnit.
What are TestNG Listeners?
One of the important features of the TestNG framework is listeners. It is an interface that listens to predefined events in test scripts and modifies the default behavior of the TestNG tool. Whether you want to customize reports or generate logs for specific tests, TestNG listeners help you to do so. Testers would also want to define prerequisites and clean-up configurations for each test project. Automate the process of setting up the prerequisites before starting your testing process. Performing clean-up operations after the testing finishes with a TestNG listener.
There are different types of Listeners in TestNG.
ITestListener
ISuiteListener
IReporter
IAnnotationTransformer
IAnnotationTransformer2
IMethodIntercepter
IHookable
IConfigurable
IConfigurationListener
IExecutionListener
IInvokedMethodIntercepter
IInvokedMethodIntercepter2
While multiple listeners exist, not every listener is regularly used. Other popular TestNG listeners include ITestListerner, ISuiteListener, and Ireporter.
Each TestNG Listener contains different methods invoked to perform a specific task. For instance, when a test case fails or is skipped, you might want to take a screenshot of that particular test case to see what went wrong. In that case, you can invoke the onTestFailure() method within the ITestListener and move the test execution to a specific block and execute a specific event.
For instance, the ITestListner contains the following methods.
onStart(): Invoked at the start of a test.
onTestFailure(): Invoked when the test fails
onTestSuccess(): Invoked when a test passes
onTestSkipped(): Invoked when skipping tests.
onFinish(): Invoked when finishing tests.
onTestFailedButWithinSuccessPercentage(): Invoked when the test fails but the results lie within the success percentage.
IReporter Listener
Generate customized reports with the IReporter Listener. It invokes the generateReport() method when executing all tests that take the following arguments:
suites: The object that contains the suite information such as package, test method, class, test results, etc.
xmlSuite: It is the XML file containing the list of suites that are to be executed.
IInvokeMethod:
This is a TestNG listener interface, used to perform specific actions before and after tests.
beforeInvocation(): Invoked before each test.
afterInvocation(): Invoked after each test.
TestNG tng = new TestNG(); tng.addListener(new MyTestListener()); tng.setTestClasses(new Class[] { MyTest.class }); tng.run();
What you can do with TestNG Listeners:
You can use TestNG listeners to perform a wide range of tasks, such as logging test results, taking screenshots, generating custom reports, modifying test methods or classes at runtime, retrying failed tests, and more.
For example, you can use the ITestListener interface to log the start and end of each test method and to take a screenshot when a test fails. Or you can use the IReporter interface to generate a custom HTML report that includes additional information about your tests, such as test data, environment details, and more.
Overall, TestNG listeners provide a powerful and flexible way to monitor and react to events that occur during the test execution cycle, and they can help you to build more robust and reliable tests.
What is the difference between TestNG listener and WebDriver listener?
We use TestNG listeners to perform operations before and after a test method is executed. On the other hand, we use WebDriver listeners to listen to WebDriver events like navigating to a new URL and clicking an element.
How to implement ITestListener in TestNG
This section will explain step by step how to use listeners in TestNG to invoke various functions. It is important to note here that Listeners can implement in two ways in TestNG:
At the class level: Annotating listeners on each class in the test code.
At the suite level: Define the class names to implement listeners in the TestNG XML file.
So first, we will go with implementing the listeners at the class level.
To implement ITestListener, we need to create a class with all the methods that we want to override. Let's call it ListenersTestng.java
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class ListenersTestNG implements ITestListener {
public void onStart(ITestContext context) {
System.out.println("onStart method started");
}
public void onFinish(ITestContext context) {
System.out.println("onFinish method started");
}
public void onTestStart(ITestResult result) {
System.out.println("New Test Started" +result.getName());
}
public void onTestSuccess(ITestResult result) {
System.out.println("onTestSuccess Method" +result.getName());
}
public void onTestFailure(ITestResult result) {
System.out.println("onTestFailure Method" +result.getName());
}
public void onTestSkipped(ITestResult result) {
System.out.println("onTestSkipped Method" +result.getName());
}
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
System.out.println("onTestFailedButWithinSuccessPercentage" +result.getName());
}
}
Now that our Listeners class sets, we need to implement the listeners in another class whose events it will listen. Create a new file TestNG.java which may look like the following:import org.openqa.selenium.WebDriver;
import org.testng.SkipException;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
@Listeners(ListenersTestNG.class)public class TestNG {
WebDriver driver = new FirefoxDriver();
@Test //Success Testpublic void CloseBrowser() {
driver.close();
Reporter.log("Driver Closed After Testing");
}
@Test //Failed Testpublic void OpenBrowser() {
driver.get("https://www.demoqa.com");
String expectedTitle = "Free QA Automation Tools For Everyone";
String originalTitle = driver.getTitle();
Assert.assertEquals(originalTitle, expectedTitle, "Titles of the website do not match");
}
private int i = 1;
@Test (successPercentage = 60, invocationCount = 3) //Failing Within Successpublic void AccountTest() {
if(i < 2)
Assert.assertEquals(i , i);
i++;
}
@Test // Skip Testpublic void SkipTest() {
throw new SkipException("Skipping The Test Method ");
}
}
Listeners, when used at the class level, are used as annotations in TestNG in the form @Listeners. Whatever method triggers the Listeners' methods, it will execute the code written within that particular test method. For example, when the SkipTest method runs in the above code, it triggers the onTestSkipped method in the TestNG listener, which executes the code written in onTestSkipped. Execute the above code to see the listener's response.
All the test cases that should be triggered have shown their output on the console. Great, now we need to think that what would happen if we have multiple classes in our test code? In practical testing scenarios, it does happen a lot. Implementing the listeners at the class level will cause a lot of distress; adding and managing the listeners. Therefore, in such a case of multiple classes, we adopt the way of implementing the listeners at the suite level in the TestNG XML file.
Implementing ITestListener is Suit Level
To implement the ITestListener at the suite level, remove the @Listener annotation from the test code, and add the following to the XML file.
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" ><suite name="ListenerExecution"><listeners><listener class-name = "ListenersTestNG"></listener></listeners><test name="ExecutingListeners"><classes><class name="TestNG"></class></classes></test></suite>
The file that contains the listener code comes under <listener class-name> tag.
Run the TestNG suite, and it will produce the same output as before. You can mention as many classes under the classes tag as you wish.
Summary:
Listeners are required to generate logs or customize TestNG reports in Selenium Webdriver.
There are many types of listeners and can be used as per requirements.
Listeners are interfaces used in selenium web driver script
Demonstrated the use of Listener in Selenium
Implemented the Listeners for multiple classes
Conclusion
TestNG Listener is a handy feature for testing and QA teams to easily automate testing projects and easily identify how each is performing. For a failed test or a skipped test, you can take the screenshot and identify why the test failed or skipped.