2
votes

We defined one testng result listener which help us to send the testing result for each test case defined in testng.xml to one internal tool such like below:

public class TestResultsListener implements ITestListener, ISuiteListener {

  @Override
  public void onFinish(ISuite suite){

    // some code to send the final suite result to internal tools
    }
  @Override
  public void onTestSuccess(ITestResult iTestResult) {
        this.sendResult(iTestResult,"PASS");Result
    }

  private void sendStatus(ITestResult iTestResult, String status){
        // Set test case information
        ......
       jsonArr.add(testResult);

    }

}

And then we integrated this listener to other project's testng xml file such like:

  <listeners>
    <listener class-name="com.qa.test.listener.TestesultsListener" />
</listeners>

It worked as designed: once the test suite finishes, the test result will be uploaded to internal tools.

Now we have one requirement that in one project, one test case in testng.xml is related to 3 test cases in internal tool which means that for one test case in testng.xml we need to update 3 test cases in internal tools. How can we update our current testng listener to fulfill this?

Thanks a lot.

1
If I understand well, each of your testng test is mapped to one or more tests in the internal tool.Benoit

1 Answers

2
votes

You can annotate each of your tests with the list of corresponding internal test tool ids:

Here I suppose that you have 2 testng tests: one is related to internal test IT-1, and the other one to internal tests IT-2, IT-3 and IT-4:

@Listeners(MyTestListener.class)
public class TestA {

    @Test
    @InternalTool(ids = "IT-1")
    public void test1() {
        System.out.println("test1");
        fail();
    }

    @Test
    @InternalTool(ids = {"IT-2", "IT-3", "IT-4"})
    public void test2() {
        System.out.println("test2");
    }
}

The annotation is simply defined like this:

@Retention(RetentionPolicy.RUNTIME)
public @interface InternalTool {
    String[] ids();
}

The your listener has just to figure out which annotation are present on successful/failed tests:

public class MyTestListener extends TestListenerAdapter implements ITestListener {

    @Override
    public void onTestSuccess(ITestResult tr) {
        super.onTestSuccess(tr);
        updateInternalTool(tr, true);
    }

    @Override
    public void onTestFailure(ITestResult tr) {
        super.onTestFailure(tr);
        updateInternalTool(tr, false);
    }

    private void updateInternalTool(ITestResult tr, boolean success) {
        InternalTool annotation = tr.getMethod().getConstructorOrMethod().getMethod().getAnnotation(InternalTool.class);
        for (String id : annotation.ids()) {
            System.out.println(String.format("Test with id [%s] is [%s]", id, success ? "successful" : "failed"));
        }
    }
}

The following output is produced:

test1
Test with id [IT-1] is [failed]

test2
Test with id [IT-2] is [successful]
Test with id [IT-3] is [successful]
Test with id [IT-4] is [successful]

You can also extend this mechanism to Suite listeners as well.

Disclaimer: The line InternalTool annotation = tr.getMethod().getConstructorOrMethod().getMethod().getAnnotation(InternalTool.class); is not bullet-proof (high risk of null pointer exception). Should be more robust.