Search code examples
javaunit-testingjboss-arquillianjunit5

How to implement a custom runner in JUnit5


Is there some way to have complete control over execution of test methods (including before/after methods) in JUnit5, similar to JUnit4 @RunWith annotation)?

I'm trying to build a JUnit5 Arquillian extension, but since Aquillian basically needs to execute each test in a container, I'm coming to a problem when running Arquillian from a Junit5 extension.

My code is here: BasicJunit5ArquillianTest.java

The test should run all methods (including before/after) in a separate container, which can be a separate JVM, remote or embedded server or anything isolated. My extension runs the test method from beforeEach hook, using Arquillian to transfer the test class and run it in a container using LauncherFactory.create(), collect test results and transfer them back.

The problem is that the test methods are executed twice - via normal JUnit5 execution and via my Arquillian extension from a beforeEach hook. I'd like to run tests only via Arquillian and skip normal execution of methods.

Is this possible in a JUnit5 extension? Or I need to create a custom test engine, possibly extending the Jupiter test engine?


Solution

  • There is no extension point (yet?) that allows you to define where or how tests are run. This is already true for threads, which means there is no way to run them on JavaFX application thread or Swing EDT.

    You might have to go deeper and implement an engine but that means that users have to choose between writing Arquillian tests or writing Jupiter tests.

    UPDATE: In a newer version of JUnit 5 released since this answer was accepted, JUnit 5 now provides the InvocationInterceptor extension point, which is exactly what is needed to implement a custom runner as an extension, which has a full control over how the tests are executed and can even replace the body of the test method with something completely different (e.g. run the test in a different JVM and return the result).