Search code examples
javatestngtestng-dataprovider

How to get testcase data on method invocation in TestNG?


I am using the IInvokedMethodListener in the TestNG package to listen for each method execution of my test case. In each method, I am trying to retrieve the data (test case data) for each case.

I have been searching around the API but am unable to find any useful methods. Has anyone tried something similar and is successful?


Solution

  • Here's how you do it.

    A test class sample that feeds off of parameters from the suite xml.

    import org.assertj.core.api.Assertions;
    import org.testng.annotations.Parameters;
    import org.testng.annotations.Test;
    
    public class TestClassUsingParameters {
    
        @Parameters({"studentName", "studentAge"})
        @Test
        public void testMethod(String name, int age) {
            Assertions.assertThat(name).isNotEmpty();
            Assertions.assertThat(age).isGreaterThan(0);
        }
    }
    

    A test class sample that feeds off of parameters from a data provider.

    import org.assertj.core.api.Assertions;
    import org.testng.annotations.DataProvider;
    import org.testng.annotations.Test;
    
    public class TestClassUsingDataProvider {
        @Test(dataProvider = "dp")
        public void testMethod(String name, int age) {
            Assertions.assertThat(name).isNotEmpty();
            Assertions.assertThat(age).isGreaterThan(0);
        }
    
        @DataProvider(name = "dp")
        public Object[][] getData() {
            return new Object[][]{
                    {"Jack Daniels", 10},
                    {"Napolean", 15}
            };
        }
    }
    

    Here's how the listener implementation would look like, which prints the parameters that are fed into the test method in either cases.

    import org.testng.IInvokedMethod;
    import org.testng.IInvokedMethodListener;
    import org.testng.ITestResult;
    
    import java.util.Arrays;
    
    public class SampleListener implements IInvokedMethodListener {
    
        @Override
        public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
            Object[] parameters = testResult.getParameters();
            if (parameters != null) {
                printer("beforeInvocation", method, parameters);
            }
        }
    
        @Override
        public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
            Object[] parameters = testResult.getParameters();
            if (parameters != null) {
                printer("afterInvocation", method, parameters);
            }
        }
    
        private void printer(String prefix, IInvokedMethod method, Object[] parameters) {
            String msg = String.format("Running %s() for method %s() with parameters: %s", prefix,
                    method.getTestMethod().getMethodName(),
                    Arrays.toString(parameters));
            System.err.println(msg);
        }
    }
    

    Finally here's how the suite xml looks like

    <?xml version="1.0"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="48697918_suite" verbose="2">
        <listeners>
            <listener class-name="com.rationaleemotions.stackoverflow.qn48697918.SampleListener"/>
        </listeners>
        <test name="48697918_test1">
            <classes>
                <class name="com.rationaleemotions.stackoverflow.qn48697918.TestClassUsingParameters">
                    <parameter name="studentName" value="Jack Daniels"/>
                    <parameter name="studentAge" value="15"/>
                </class>
                <class name="com.rationaleemotions.stackoverflow.qn48697918.TestClassUsingDataProvider"/>
            </classes>
        </test>
    </suite>
    

    Here's the output:

    ...
    ... TestNG 6.14.2 by Cédric Beust ([email protected])
    ...
    
    Running beforeInvocation() for method testMethod() with parameters: [Jack Daniels, 15]
    
    Running afterInvocation() for method testMethod() with parameters: [Jack Daniels, 15]
    Running beforeInvocation() for method testMethod() with parameters: [Jack Daniels, 10]
    Running afterInvocation() for method testMethod() with parameters: [Jack Daniels, 10]
    Running beforeInvocation() for method testMethod() with parameters: [Napolean, 15]
    Running afterInvocation() for method testMethod() with parameters: [Napolean, 15]
    PASSED: testMethod("Jack Daniels", 15)
    PASSED: testMethod("Jack Daniels", 10)
    PASSED: testMethod("Napolean", 15)
    
    ===============================================
        48697918_test1
        Tests run: 3, Failures: 0, Skips: 0
    ===============================================
    
    ===============================================
    48697918_suite
    Total tests run: 3, Failures: 0, Skips: 0
    ===============================================