TestNG | Simplify listener code and access class objects through reflection

You can extend an abstract class containing your library, driver, and default listeners to your test classes. This will keep you from having to recreate many portions of your code over and over for each test class. Also, by extension, this will provide you access to all important test class level objects to your custom TestNG listeners through reflection.

By extending a class to your test methods, which exposes the library used to set up and control the driver, you allow yourself easy access to these class objects from a custom listener regardless of which test or class was fed to the listener. This could be useful for gathering device/driver-related information for reporting purposes.

First, see TestNG | Custom TestNG listeners using ITestListener to familiarize yourself with the custom listeners. Then, you want to create a new Java class and place the label abstract between the access modifier and the class object type in the class definition.

Copy
public abstract class ClassHelper {

}

Now extend the abstract class to your test class.

Copy
public class AmazonTestSystem extends ClassHelper {

}

Next, you can move your driver, library, and any other objects that you expose to all test methods into the abstract class. You could also implement your beforeMethod, beforeClass, and so on, listeners here.

Copy
public abstract class ClassHelper {
    private RemoteWebDriver driver;
    public library lib;
   

    @BeforeMethod(alwaysRun = true)
    public void beforeMethod(Method method) {

    }

    @AfterMethod(alwaysRun = true)
    public void afterMethod(Method method) {

    }
}

Back in the test class, you would still initialize your page-level objects as normal so as not to initialize all classes when they are not really needed. If you have a small number of page objects, you could also move this into the ClassHelper if you desired.

Copy
public class AmazonTestSystem extends ClassHelper { 
   private androidHelper android;
    private amazonHome homePage;
    private amazonSearchResults searchResultsPage;
    private amazonCartFunctions cart;

public void setPagesAndHelpers(library lib) throws IOException {
        // initializes the androidHelper class
        android = new androidHelper(lib);
        // sets up the home page class
        homePage = new amazonHome(lib);
        // sets up the search results class
        searchResultsPage = new amazonSearchResults(lib);
        // sets up the cartFunctions class
        cart = new amazonCartFunctions(lib);
        lib.loadPropertyFile("_amazonElements.properties");
    }


    @Test
    public void OrderBook() throws InterruptedException, IOException {
        // sets the RemoteWebDriver and initial library settings
        try {
            setPagesAndHelpers(lib);
    }
}

Last, to get access to the ClassHelper objects from a customer listener, use reflection.

Copy
public class TestListener implements ISuiteListener, ITestListener, IInvokedMethodListener {

        @Override    
        public void onTestSkipped(ITestResult arg0) {            
            setDetails("Skip", arg0);    
        }

        public void setDetails(String result, ITestResult testResult) {
            Object currentClass = testResult.getMethod().getInstance();
            ClassHelper classHelper = ((ClassHelper) currentClass);

            //do something with the class objects
            // classHelper.lib

        }

}