How can I get TestNG ITestResult in Spring test listener?

1.3k views Asked by At

I'm writing tests using Spring and TestNG. An example of a test class:

@SpringBootTest
@TestExecutionListeners(
        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS,
        listeners = {TestListener.class}
)
public class BaseTest extends AbstractTestNGSpringContextTests
{
}

My TestListener class extends TransactionalTestExecutionListener so I have override methods for beforeTestClass(TestContext testContext), afterTestMethod(TestContext testContext) etc.

My problem is that within afterTestMethod I need to be able to get the TestNG ITestResult or TestResult so I can do different things depending on test success, fail or skip etc. Is there any way I can access ITestResult or TestResult from a spring test listener?

1

There are 1 answers

1
Krishnan Mahadevan On BEST ANSWER

There is no easy direct way of getting access to the ITestResult object of a test method that was executed because Spring doesn't seem to provide access to it.

You can try doing something like this:

  • Build a utility method such that when given a Method object that represents a @Test method that was just executed, it would query the current ITestContext and find any ITestResult object whose Method object would match with the Method object that was provided.
  • Have your listener implementation query this utility method to get access to the ITestResult object.

Here's how a sample implementation could look like:

public class MyListener extends TransactionalTestExecutionListener {
    @Override
    public void afterTestMethod(TestContext testContext) throws Exception {
      super.afterTestMethod(testContext);
      ITestResult currentTestResult = getCorrespondingResultFor(testContext.getTestMethod());
    }

    private ITestResult getCorrespondingResultFor(Method method) {
      ITestContext context = Reporter.getCurrentTestResult().getTestContext();
      Set<ITestResult> allResults = new HashSet<>();
      allResults.addAll(context.getPassedTests().getAllResults());
      allResults.addAll(context.getFailedTests().getAllResults());
      allResults.addAll(context.getSkippedTests().getAllResults());
      return allResults
          .stream()
          .filter(result -> result.getMethod().getConstructorOrMethod().getMethod().equals(method))
          .findAny()
          .orElse(null);
    }
}