How to run modular multi-package JUnit test suits?

333 views Asked by At

I'm trying to run all tests (packaged across many different subpackages) in a given (Java-16, modular) project, using the test suite feature of JUnit (4); but this is much harder than I'd like it to be, seemingly requiring an -add-opens JVM option per test (sub)package. Does a better solution exist?

A MVE would be a project mve with test suite

package mve.test;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

import mve.test.sub.HelloTest;

@RunWith(Suite.class)
@Suite.SuiteClasses(HelloTest.class)
public class AllTests {
    // Empty by design.
}

and the (only) test in the subpackage mve.test.sub being

package mve.test.sub;

import org.junit.Test;

import mve.main.Hello;

public class HelloTest {
    @Test
    public void test() {
        Hello.main(null);
    }
}

The project exports nothing and requires nothing, which is how I'd like to keep it.

Is there any way to do this without adding --add-opens mve/mve.test.xxx=ALL-UNNAMED for each and every single subpackage xxx to the JVM?

If not, this is a heavy blow against using (a lot of) packages for your test classes.

1

There are 1 answers

3
sys64738 On

With Junit 5 it works like this:

Create a suite class to run the tests of all modules like this:

package com.project;

import org.junit.platform.suite.api.SelectModules;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectModules({
  "com.module1",
  "com.module2",
  "com.module3",
})
class AllTests {}

In each tested module the exported packages have to be opened to Junit, e.g.:

module com.module1
{
  exports com.module1.packageA;
  exports com.module1.packageB;
  
  opens com.module1.packageA to org.junit.platform.commons;
  opens com.module1.packageB to org.junit.platform.commons;
  
  requires org.junit.jupiter.api;
  requires ...
}

And of course each module must have its own tests inside.