Gerard Murphy
Gerard Murphy

Reputation: 1

Accessing the `UniqueId` passed to a JUnit5 Session from inside an Extension

Background:

https://github.com/sageserpent-open/americium/issues/69

https://github.com/sageserpent-open/americium/issues/66

These concern an extension that generates test data for a JUnit5 test, analogous to @ParameterizedTest. When running a test from an IDE such as IntelliJ, clicking on a specific test case results in a UniqueId specific to that test case being sent to JUnit5 via its Launcher API, wrapped up in a LauncherDiscoveryRequest.

This finds its way down to some filtering logic in TestTemplateTestDescriptor. The filter checks the UniqueId for each potential test case against the one passed to the Launcher, so only those test cases (usually just one of them) is run.

So far, so good.

Problem:

The problem I have is that instead of ploughing through all the test cases (because 1. this can take a long time and 2. sometimes the test cases are produced in a non-deterministic fashion that depends on the outcome of whether the previous test cases passed or failed), I want the extension to use the UniqueId passed via Launcher to directly generate the corresponding test case only. This would still be passed through the aforementioned filtration, but the extension needs to get upfront access to that UniqueId.

What I tried:

There is a callback TestExecutionListener.dynamicTestRegistered that seems to do the right thing, only investigation shows that it is called just prior to each test case being run, downstream of the filtration and the generation of the test cases. I need this to happen upfront, specifically in the implementation of TestTemplateInvocationContextProvider.provideTestTemplateInvocationContexts.

That method is passed a ExtensionContext with a UniqueId property, but it refers to the entire test class and not the one I'm after that identifies the specific test case.

Tantalisingly, the actual implementation passed in is a TestTemplateExtensionContext and that does contain a TestTemplateTestDescriptor that in turn contains a filter with the desired UniqueId in there, but none of that is accessible without reflection and a lot of unsafe assumptions.

What I want:

Is there a clean way of getting that top-level UniqueId passed to the Launcher from my extension?

Upvotes: 0

Views: 62

Answers (1)

Gerard Murphy
Gerard Murphy

Reputation: 1

From the comments, this grants access to the unique id(s) for the replayed test case(s) in the LauncherDiscoveryRequest without breaking abstractions:

public class LauncherDiscoveryListenerOpenSesame
        implements LauncherDiscoveryListener {
    @Override
    public void launcherDiscoveryStarted(LauncherDiscoveryRequest request) {
        final List<UniqueId> uniqueIds = request
                .getSelectorsByType(UniqueIdSelector.class)
                .stream()
                .map(UniqueIdSelector::getUniqueId)
                .collect(
                        Collectors.toList());

        System.out.println(uniqueIds);

        LauncherDiscoveryListener.super.launcherDiscoveryStarted(request);
    }
}

Upvotes: 0

Related Questions