TestNG | Custom listeners using IInvokedMethodListener

With the IInvokedMethodListener, you can perform a certain action before/after a method has been executed, for example cleanup or setup. Unlike ITestListener, this listener runs before and after every method you have in the class (Before and After class, suite, test) even if you see only two methods included in the listener itself:

  • afterInvocattion(): Invoke after each method

  • beforeInvocation(): Invoke before each method

As for the other type of listeners, you need to create a class, import the listener, and  implement a listener interface in the class.

In Eclipse, you can use the tooltip to correct errors: hover over the class name and select the option to add unimplemented methods. This will automatically add both of the listener methods, as follow:

Copy
package listenerspackage;

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;

public class CustomListener1 implements IInvokedMethodListener {

    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        // Before every method in the Test Class
        System.out.println("beforeInvocation: runs before every method in the Test Class");
    }

    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        // After every method in the Test Class
        System.out.println("afterInvocation: "runs after every method in the Test Class);
    }
}


Now, you have to hook this listener into your framework. You can do this from inside your test class by using Listener annotation, as follows:

Copy
package testclasses;

import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import listenerspackage.CustomListener1;

// add Listeners annotation, in order to let your test class knows, that there is a Listener that will listen for the execution proccesses
@Listeners(CustomListener1.class)
public class TestNG_ListenersTest1 {
    
    @BeforeClass
    public void setUp() {
        System.out.println("Code in before class");
    }
    
    @AfterClass
    public void cleanUp() {
        System.out.println("Code in after class");
    }
    
    @Test
    public void testMethod1() {
        System.out.println("Code in testMethod1");
    }
    
    @Test
    public void testMethod2() {
        System.out.println("Code in testMethod2");
    }
}

Alternatively, you can hook up the listener by adding it in your testng.xml. Following is the xml option:

Copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" thread-count="2">
    <listeners>
        <listener class-name="org.uncommons.reportng.HTMLReporter"/>
    </listeners>
    <test name="Application Test">
        <classes>
            <class name="testclasses.TestNG_ListenersTest1"></class>
        </classes>
    </test>
</suite>