3

I'm trying to port Test Management For Jira JUnit Integration to JUnit5. This module generates a JSON report of the test run and associates the results with Jira tickets by using annotations on the test methods, example.

From the TestExecutionListener I'm not sure what the best approach to retrieve the TestCase annotation is.

I looked at Reflection using the TestIdentifier.getSource and doing manipulations to rebuild the method signature and extracting the annotation from there but the approach felt clumsy.

I came across this post Allow extensions to register TestExecutionListeners which proposed the following:

Proposal: Have your extension publish the WebDriver bean's session id, e.g.

String sessionId = ...;
extensionContext.publishReportEntry("webDriverSessionId", sessionId)

In your TestExecutionListener, implement reportingEntryPublished and store it in a Map with the TestIdentifier as a key. In executionFinished report the test outcome along with the value from this Map.

This approach looks promising but I want to make sure there isn't another way that doesn't require both an extension and a test execution listener. Is there a way to retrieve test method annotation information directly in the TestExecutionListener?

  • 1
    If you don't have a concrete need for implementing `TestExecutionListener`, you can implement the `TestWatcher` extension API for JUnit Jupiter and register that extension either via your custom annotation (i.e., meta-annotated with `@ExtendWith(MyExtension.class)` or via the global registration mechanism. In your custom `TestWatcher` extension, you can access the current test method via the `ExtensionContext` and then look up your annotation on the method. – Sam Brannen Jul 18 '19 at 14:18
  • @SamBrannen I have a working solution using the method you described above and I do require the TestExecutionListener to write the report to file on testPlanExecutionFinished. I only need the Extension to capture the value associated with my annotation. I'm now trying to extend this to support ParameterizedTest I looked at getting the value from the parameters but ran into [Introduce extension API for accessing arguments passed to tests](https://github.com/junit-team/junit5/issues/1139). I'm now trying to use TestReporter to publish the TestCaseKey in the test definition. –  Jul 18 '19 at 15:04
  • Sounds like you're on the right track! – Sam Brannen Jul 19 '19 at 16:35
  • There shouldn't be any problem with accessing the parameters (`java.lang.reflect.Parameter`) for a `@ParameterizedTest`. That should work the same as for any method (`@Test`, etc.). Or do you really need to access the physical runtime _arguments_ passed to the method? – Sam Brannen Jul 19 '19 at 16:36
  • @SamBrannen sorry for the delay in my response, I appreciate you taking the time. I created this [gitproject](https://github.com/alexandre-senecal/tm4j_junit5) which demonstrates what I'm looking to accomplish and were I fall short. –  Jul 31 '19 at 19:35

2 Answers2

1

Seems like you can't get test annotation from TestExecutionListener but instead you can implement TestWatcher or e.g AfterEachCallback and get custom annotation value like that:

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestWatcher;

public class MyExtention implements TestWatcher, AfterEachCallback {


    @Override public void testSuccessful(ExtensionContext context) {
        if (context.getElement().isPresent() && context.getElement().get().isAnnotationPresent(MyCustomAnnotation.class)) {
            int val = context.getElement().get().getAnnotation(MyCustomAnnotation.class).value();
            // Report on success
        }
    }

    @Override public void afterEach(ExtensionContext context) throws Exception {
        if (context.getElement().isPresent() && context.getElement().get().isAnnotationPresent(MyCustomAnnotation.class)) {
            int val = context.getElement().get().getAnnotation(MyCustomAnnotation.class).value();
            // Report each
        }
    }
}

noriks
  • 81
  • 1
  • 5
0

@Alex, the following might be used inside the listener... ((MethodSource) testIdentifier.source).javaMethod.getAnnotation(TestCase.class)

Keyholder
  • 29
  • 2