Hi Marc,

With forkCount = 1 it works fine, the problem is with forkCount > 1. The
Arquillian extension registers its state in the store at the root of the
TestPlan. When running with forkCount > 1, surefire sets up a load balancer
in the main process. This load balancer streams tests one by one to the
forks. The forks run a test, and request the next one when done. This is
implemented by creating a LauncherDiscoveryRequest per test. This in turn
results in a separate TestPlan per test, causing the state of Arquillian to
be rebuilt over and over again. When running with forkCount = 1, only a
single LauncherDiscoveryRequest is created and all tests are part of the
same TestPlan.

The Arquillian extension can be modified to use a LauncherSessionListener,
but this will require changes to the code base. The same is probably true
for other extensions.

Best regards,
Emond

On Mon, Sep 13, 2021 at 7:51 AM Marc Philipp <m...@gradle.com> wrote:

> Hi Emond,
>
> could you please elaborate why the LauncherSessionListener approach
> doesn’t work for forkCount=1 for Arquillian?
>
> Cheers,
>
> Marc
>
> On Sunday, Sep 12, 2021 at 9:37 PM, Emond Papegaaij <
> emond.papega...@gmail.com> wrote:
> Hi Marc,
>
> Thanks for the links to the documentation. This really helps for my
> Arquillian-Spock extension. It's good to know the LauncherSession was
> introduced to solve this issue.
>
> The problem I see with this new API is that it requires the extension to
> explicitly make use of it. For example, the JUnit 5 Arquillian extension
> will need to be adapted to this new API to work correctly with a forkCount
>
> 1. The same will probably hold for other extensions. The cause of this is
>
> that separate invocations of the launcher do not really share a life
> cycle.
> LauncherSession is able to bind these invocations together, but the engine
> will be run over and over again. JUnit does support streaming tests in a
> lazy way via the DynamicTest API. It would be great if this could somehow
> be exposed via the LauncherDiscoveryRequest. That would IMHO really solve
> this issue.
>
> Best regards,
> Emond
>
> On Sat, Sep 11, 2021 at 7:52 AM Marc Philipp <m...@gradle.com> wrote:
>
> Hi Emond and Tibor,
>
> I’m glad you discovered the new LauncherSession API which was added for
> this purpose. The JUnit 5.8 GA release will come in the next few days.
>
> As you mentrioned, the official documentation does not (yet!) do a good
> job of explaining its intended use case:
>
>
> https://junit.org/junit5/docs/5.8.0-RC1/user-guide/#launcher-api-launcher-session-listeners-custom
>
> Here’s a more complete example that I wrote for Gradle’s test distribution
> plugin:
>
>
> https://docs.gradle.com/enterprise/test-distribution-gradle-plugin/#junit_5_8_and_later
>
> It demonstrates how to initialize a “fixture” only once for an entire
> session and only if tests are actually going to be executed not just
> discovered. I’ll make sure to update the official JUnit docs to include a
> similar example before the release.
>
> To only differentiate between the different versions of JUnit in one place
> and stay backwards compatible, you could create an adapter class like
> this:
>
> public class BackwardsCompatibleLauncherSession implements AutoCloseable {
>
> public static BackwardsCompatibleLauncherSession open() {
> try {
> LauncherSession launcherSession =
> LauncherFactory.openSession();
> return new
> BackwardsCompatibleLauncherSession(launcherSession.getLauncher(),
> launcherSession::close);
> } catch (NoSuchMethodError ignore) {
> // JUnit Platform version on test classpath does not yet
> support launcher sessions
> return new
> BackwardsCompatibleLauncherSession(LauncherFactory.create(), () -> {});
> }
> }
>
> private final Launcher launcher;
> private final Runnable onClose;
>
> private BackwardsCompatibleLauncherSession(Launcher launcher, Runnable
> onClose) {
> this.launcher = launcher;
> this.onClose = onClose;
> }
>
> Launcher getLauncher() {
> return launcher;
> }
>
> @Override
> public void close() {
> onClose.run();
> }
> }
>
> Cheers,
>
> Marc
>
>

Reply via email to