Collecting test output from tests run with Junit parallelization

We have a test suite where each test class can be run in parallel. Initially I enabled the parallelization with Junit (https://junit.org/junit5/docs/5.3.0-M1/user-guide/index.html#writing-tests-parallel-execution). The tests ran fine but the output associated with a given test seemed to be unreliable. Sometimes I would see no output for the test or see output from another test. I opened this question on StackOverflow for the issue: https://stackoverflow.com/questions/63346743/junit-5-parallel-test-execution-loses-output-from-tests
After checking other sources, I learned that this is due to how Gradle collects test output and is due to the assumption that the tests will be executed in a single thread. As recommended elsewhere, I disabled the Junit parallelization and instead set it in Gradle with “forkEvery 1”. As mentioned in the Gradle docs this is pretty inefficient, but it’s still faster than potentially have two tests which take 5 minutes run sequentially. I noticed today that if I include a tests filter, that only seems to take effect after Gradle has created a new process per test class.

I’d like to try to write a custom adapter between Junit and Gradle to collect the test output properly. How would I go about doing that? Are there any existing examples to read through which do something similar?

You could move the slow tests to src/slow-test/java and then add another Test task to the project with forkEvery=1. This way the bulk of your tests can share the same jvm(s) and have less startup overhead but your slow tests are guaranteed to run in parallel.

If you want the slow tests to run in parallel to the main tests, move them to a separate project and pass the --parallel flag (or equivalent property). Gradle will only run tasks in separate projects in parallel, never the same project.

Thanks for the suggestion @Lance! Unfortunately it’s not just some of the tests that are slow. These are API tests, so each test could take a while due both to the response times for the individual requests as well as timeouts added to wait for the result of asynchronous processing.