gradlex-org / java-module-testing

Gradle plugin to turn JVM Test Suites into Blackbox or Whitebox Test Suite for Java Modules
Apache License 2.0
15 stars 5 forks source link
gradle-plugin java java-modules jpms testing

Java Module Testing Gradle plugin

Build Status Gradle Plugin Portal

A Gradle 7.4+ plugin to turn a JVM Test Suite into a Blackbox or Whitebox Test Suite for Java Modules.

This plugin is maintained by me, Jendrik Johannes. I offer consulting and training for Gradle and/or the Java Module System - please reach out if you are interested. There is also my YouTube channel on Gradle topics.

If you have a suggestion or a question, please open an issue.

Java Modules with Gradle

If you plan to build Java Modules with Gradle, you should consider using these plugins on top of Gradle core:

Here is a sample that shows all plugins in combination.

In episodes 31, 32, 33 of Understanding Gradle I explain what these plugins do and why they are needed.

Full Java Module System Project Setup is a full-fledged Java Module System project setup using these plugins.

How to use?

For a quick start, you can find some samples here:

For general information about how to structure Gradle builds and apply community plugins like this one to all subprojects you can check out my Understanding Gradle video series.

Plugin dependency

Add this to the build file of your convention plugin's build (e.g. build-logic/build.gradle(.kts) or buildSrc/build.gradle(.kts)).

dependencies {
    implementation("org.gradlex:java-module-testing:1.5")
}

Apply the plugin

In your convention plugin, apply the plugin.

plugins {
    id("org.gradlex.java-module-testing")
}

Blackbox Test Suites

The plugin automatically turns JVM Test Suites into Blackbox Test Suites if the src/<test-suite-name>/module-info.java file exists. A blackbox test suite is a separate module itself. See documentation on JVM Test Suites for more details on creating and configuring test suites.

Whitebox Test Suites

The plugin automatically turns JVM Test Suites without module-info.java file into Whitebox Test Suites. Whitebox Test Suites might require additional configuration, which can be done like this:

javaModuleTesting.whitebox(testing.suites["test"]) {
    requires.add("org.junit.jupiter.api")
    // opensTo.add("org.junit.platform.commons") <-- opensTo 'org.junit.platform.commons' is done by default
    // exportsTo.add("...")
}

See documentation on JVM Test Suites for more details on creating and configuring test suites.

Alternatively, you can put the requires into a module-info.java file using the same notation that you would use for blackbox tests. For this, you need to create the file in <src-set-location>/java9/module-info.java. For example:

src
  ├── main
  │   └── java
  │       ├── module-info.java
  │       └── ...
  └── test
      ├── java
      │   └── ...
      └── java9
          └── module-info.java
              | module org.example.app.test {
              |   requires org.example.app; // 'main' module into which the tests are patched
              |   requires org.junit.jupiter.api;
              | }

A whitebox test source set does not have a module-info.java. Instead, the main and test classes will be patched together and the test will run in the main module which now includes the test classes as well. Additional requires for the test are defined as shown above. If the sources under test are located in a different source set (not main), this can be configured via sourcesUnderTest.set("source-set-name").

Classpath Test Suites

An alternative variant of "whitebox" testing is to run testing on the classpath and ignore all module information. This is what Gradle does without this plugin. By default, this plugin replaces this with the Whitebox Test Suite setup, which should be the preferred testing approach. If you still need to use the classpath-based setup for a Test Suite, you may configure it as follows:

javaModuleTesting.classpath(testing.suites["test"])

A reason to do testing like this is if you need to utilise testing libraries (e.g. for mocking) that do not work with the Module System at all.

What does the plugin do?

The plugin rewires the inputs of test compilation (:compileTestJava) and test runtime (:test). This includes configuring the Module Path and adding patch parameters in the case of whitebox testing.

Blackbox Test

Changes for test runtime (:test):

Whitebox Test

Changes for test compilation (:compileTestJava):

Changes for test runtime (:test):

Disclaimer

Gradle and the Gradle logo are trademarks of Gradle, Inc. The GradleX project is not endorsed by, affiliated with, or associated with Gradle or Gradle, Inc. in any way.