1

I have prepared a Listener class to check the status of the method in the End if that is passed or failed. It's working fine, but it's being called twice after the execution of Method.

I have detailed my Listener class, TestCase class and output I'm getting below.


Listener Class:

    package com.qtpselenium.Listener;

    import java.util.List;

    import org.apache.log4j.Logger;
    import org.testng.IInvokedMethod;
    import org.testng.IInvokedMethodListener;
    import org.testng.ITestResult;
    import org.testng.Reporter;
    import org.testng.TestListenerAdapter;
    import org.testng.internal.Utils;

    public class CustomerListner extends TestListenerAdapter implements IInvokedMethodListener{
        // Listener class must be part of testng.xml
        Logger app_logs = Logger.getLogger("DEBUG");

        public void  onTestFailure(ITestResult tr) {

            app_logs.debug(tr.getName() + " :  test case has been Failed ");
            System.out.println( tr.getName() + " :  test case has been Failed ");
        }

        public void  onTestSkipped(ITestResult tr) {

            app_logs.debug(tr.getName() + " :  test case has been Skipped ");
            System.out.println(tr.getName() + " :  test case has been Skipped ");
        }

        public void  onTestSuccess(ITestResult result) {

            app_logs.debug(result.getName() + " :  test case has been Passed ");
            System.out.println(result.getName() + " :  test case has been Passed ");
        }

        public void afterInvocation(IInvokedMethod method, ITestResult result) {
            Reporter.setCurrentTestResult(result);
            System.out.println("*************TestsListenerAdapter******************");

            if (method.isTestMethod()) {
                List<Throwable> verificationFailures = ErrorUtil.getVerificationFailures();
                //if there are verification failures...
                if (verificationFailures.size() != 0) {
                    //set the test to failed
                    result.setStatus(ITestResult.FAILURE);

                    //if there is an assertion failure add it to verificationFailures
                    if (result.getThrowable() != null) {
                        verificationFailures.add(result.getThrowable());
                    }

                    int size = verificationFailures.size();
                    //if there's only one failure just set that
                    if (size == 1) {
                        result.setThrowable(verificationFailures.get(0));
                    } else {
                        //create a failure message with all failures and stack traces (except last failure)
                        StringBuffer failureMessage = new StringBuffer("Multiple failures (").append(size).append("):nn");
                        for (int i = 0; i < size-1; i++) {
                            failureMessage.append("Failure ").append(i+1).append(" of ").append(size).append(":n");
                            Throwable t = verificationFailures.get(i);
                            String fullStackTrace = Utils.stackTrace(t, false)[1];
                            failureMessage.append(fullStackTrace).append("nn");
                        }

                        //final failure
                        Throwable last = verificationFailures.get(size-1);
                        failureMessage.append("Failure ").append(size).append(" of ").append(size).append(":n");
                        failureMessage.append(last.toString());

                        //set merged throwable
                        Throwable merged = new Throwable(failureMessage.toString());
                        merged.setStackTrace(last.getStackTrace());

                        result.setThrowable(merged);

                    }
                }
            }

        }

        public void beforeInvocation(IInvokedMethod arg0, ITestResult arg1) {}


    }

***********************
`TestCase` class:

    package com.qtpselenium.suiteA;


    import org.testng.SkipException;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.DataProvider;
    import org.testng.annotations.Test;

    import com.qtpselenium.util.TestUtil;

    public class TestCaseA1 extends TestSuiteBase{

          String runmode[] = null;
          int count=-1;


        //Checking runMode of the Test case in Suite
        @BeforeTest
        public void checkTestcaseskip(){ 




            //this.getclass().getSimpleName() method returns the name of the class
            App_Logs.debug("checking run mode of " +this.getClass().getSimpleName() + " testcase");
            if(!TestUtil.IsTestCaseRunnable(suiteAxlsx, this.getClass().getSimpleName())){
                App_Logs.debug("Run mode of testcase " + this.getClass().getSimpleName() + " is N");
                throw new SkipException("Run mode of testcase " + this.getClass().getSimpleName() + " is N");

            }else

            App_Logs.debug("Run mode of testcase " + this.getClass().getSimpleName() + " is Y");
                 runmode =  TestUtil.getDataSetRunmode(suiteAxlsx, this.getClass().getSimpleName());

        }



        @Test(dataProvider="getTestData")
         //No of arguments passed should be equal to no of dataelement in Testcase1 and type should be matched
        public void TestcaseA1(
                              String col1,
                              String col2,
                              String col3,
                              String col4

                              ){

            count++;
            if(runmode[count].equalsIgnoreCase("N")){

                throw new SkipException("The runmode for Testdata is N for row number " + count );
            }else{
            App_Logs.debug("Test data of testcase : " +  this.getClass().getSimpleName());
            App_Logs.debug(col1+"--"+col2+"--"+col3+"--"+col4);

            }
        }
     //Data provide to TestcaseA1
        @DataProvider
        public Object[][] getTestData(){


            return TestUtil.getdata(suiteAxlsx, this.getClass().getSimpleName());


        }
    }

*****************Testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="TestNG Dadadriver suite" allow-return-values="true" > 
<!-- suite name="Suite Name" AND Please remember all the tag names should be lowered case otherwise the sytem will throw an error --> 


          <listeners>
              <!-- packagename.customerlistner_classname  -->
                       <listener class-name="com.qtpselenium.Listener.CustomListner"/>
          </listeners>

        <suite-files>
               <suite-file path="./suiteA.xml" />
               <suite-file path="./suiteB.xml" />
               <suite-file path="./suiteC.xml" />

        </suite-files>




</suite>


*******************
output:

    uite read from excel suiteA  Suite passed by calling method  suiteA
    Run mode is NforsuiteA  Test case

    *************TestsListenerAdapter******************
    Data is Returned for Test caseTestCaseA1
    *************TestsListenerAdapter******************
    TestcaseA1 :  test case has been Skipped 
    TestcaseA1 :  test case has been Skipped 
    *************TestsListenerAdapter******************
    TestcaseA1 :  test case has been Skipped 
    TestcaseA1 :  test case has been Skipped 
    *************TestsListenerAdapter******************
    TestcaseA1 :  test case has been Skipped 
    TestcaseA1 :  test case has been Skipped 
    *************TestsListenerAdapter******************
    TestcaseA1 :  test case has been Skipped 
    TestcaseA1 :  test case has been Skipped 


I have 4 data set but it's writing 8 times that test case has been skipped.
  • Did you debug your example with a breakpoint in "onTestSkipped"? – Jeroen Heier Jan 23 '17 at 17:31
  • I tried but Not getting why it's being invoked twice for each data set. –  Jan 23 '17 at 18:29
  • Hi , In my Logs i checked after the Testcase is over , it's invoking the Listener class is twice. 23/01/2017 11:39:42 DEBUG Dummy Data_A1_1--Dummy Data_A1_2--Dummy Data_A1_3--Dummy Data_A1_4 23/01/2017 11:39:42 DEBUG TestcaseA1 : test case has been Passed 23/01/2017 11:39:42 DEBUG TestcaseA1 : test case has been Passed –  Jan 23 '17 at 18:46
  • Which TestNG version do you use? Could you retry with the latest one? – juherr Jan 24 '17 at 10:36

2 Answers2

1

I had the same problem with testng newest version 6.8, by changing the dependency version in pom.xml to 6.10 solved the problem.

<dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>6.10</version>
    </dependency>
Tracy Zhou
  • 714
  • 1
  • 7
  • 11
0

I Have faced the same issue but I found the solution like below- Add the @Listeners annotation on class level (where your @Test are located)
e.g.

@Listeners(listeners.ReportListener.class)
public class Test1 
{
    @Test
    public void test1()
    {
        System.out.println("in Test1 method");
    } 
} 



but do not include listeners tag in testNg.xml under the suite tag. remove from testng.xml

Add @listeners annotation only on test class only. It will work.

Avinash Pande
  • 1,510
  • 19
  • 17