1

Some time ago, I implemented a remote test execution feature on JUnit 4 for the z2-environment (a Java server development and execution environment for large Java applications). Possibly similar to the Teleporter Rule of Apache Sling (for which I failed to find a JUnit 5 version).

This worked essentially like this:

  1. A custom Runner (Z2UnitTestRunner) is declared on the test class using @RunWith

  2. Z2UnitTestRunner passes a test invocation (actually a test description) to the remote side

  3. On the remote side the test description is executed by a TestExecutor

  4. A registered RunListener logs all test events back to the client side

  5. On the client side any registered RunNotifier will be passed the test events received from the remote side

So it is rather simple actually: It just establishes a man-in-the-middle between Runner and TestExecuter. The cool thing is: While all test execution is performed in the "native" server environment of the application, tests can be triggered from the IDE or ANT/Jenkins, as if running locally. We use that quite a lot.

I am now trying to implement support for JUnit 5. I had a deeper look lately at the various extension and configuration tweaks supported by JUnit 5 but haven't really found a complete solution yet.

The most robust solution, I think, would be to integrate with the DefaultLauncher (as that is used by IDEs and ANT as far as I can tell) or via a custom launcher. The altered behavior would make sure that selectors and filters are sent to the remote side while all TestExecutionListener events would be conveyed to be client side.

Neither approach seems to be supported currently. At least, as far as I can tell, there is no way to provide a custom Launcher nor a way to change the behavior of the DefaultLauncher. But there is a LauncherFactory and a DefaultLauncher - which looks like there IS the intention to support custom launchers (are they?)!

I also looked into implementing a custom engine that would somehow take over test execution delegated to the remote side. But that seems to be the wrong level of interception. Plus I haven't found a way to "suppress" execution via the Jupiter Engine anyway.

Currently I am looking for any good idea or example that would help me move forward. Any suggestion welcome!

gnomie
  • 439
  • 5
  • 16
  • I think the most generic approach is an engine that transports all incoming selectors to a launcher on the remote end. I haven’t thought that fully through though. Suppressing execution through Jupiter (or any other engine) can be accomplished by not having the engine on the execution path or by excluding it explicitly e.g through Gradle‘s junitPlatform configuration. Sounds like an interesting OS project I’d be happy to contribute to. – johanneslink Sep 02 '20 at 15:09
  • 1
    Using a custom engine, one could probably do the one part, i.e. forcing the remote execution. But as it should be possible to start tests from the IDE or via Ant using the regular way, behavior should probably be altered "behind" the DefaultLauncher (or the LauncherFactory). hmmm... but maybe I should turn this into a feature request that could be implemented as an OS project. Thanks for bringing that up! – gnomie Sep 05 '20 at 18:02

0 Answers0