https://github.com/gradlex-org/java-module-testing
Gradle plugin to turn JVM Test Suites into Blackbox or Whitebox Test Suite for Java Modules
https://github.com/gradlex-org/java-module-testing
gradle-plugin java java-modules jpms testing
Last synced: 23 days ago
JSON representation
Gradle plugin to turn JVM Test Suites into Blackbox or Whitebox Test Suite for Java Modules
- Host: GitHub
- URL: https://github.com/gradlex-org/java-module-testing
- Owner: gradlex-org
- License: apache-2.0
- Created: 2021-12-02T10:03:04.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-04-04T07:46:30.000Z (29 days ago)
- Last Synced: 2025-04-04T08:29:40.047Z (29 days ago)
- Topics: gradle-plugin, java, java-modules, jpms, testing
- Language: Java
- Homepage:
- Size: 544 KB
- Stars: 17
- Watchers: 2
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Java Module Testing Gradle plugin
[](https://actions-badge.atrox.dev/gradlex-org/java-module-testing/goto?ref=main)
[](https://plugins.gradle.org/plugin/org.gradlex.java-module-testing)A Gradle 7.4+ plugin to turn a [JVM Test Suite](https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html#sec:jvm_test_suite_configuration)
into a **Blackbox** or **Whitebox** Test Suite for Java Modules.This plugin is maintained by me, [Jendrik Johannes](https://github.com/jjohannes).
I offer consulting and training for Gradle and/or the Java Module System - please [reach out](mailto:[email protected]) if you are interested.
There is also my [YouTube channel](https://www.youtube.com/playlist?list=PLWQK2ZdV4Yl2k2OmC_gsjDpdIBTN0qqkE) on Gradle topics.If you have a suggestion or a question, please [open an issue](https://github.com/gradlex-org/java-module-testing/issues/new).
# Java Modules with Gradle
If you plan to build Java Modules with Gradle, you should consider using these plugins on top of Gradle core:
- [`id("org.gradlex.java-module-dependencies")`](https://github.com/gradlex-org/java-module-dependencies)
Avoid duplicated dependency definitions and get your Module Path under control
- [`id("org.gradlex.java-module-testing")`](https://github.com/gradlex-org/java-module-testing)
Proper test setup for Java Modules
- [`id("org.gradlex.extra-java-module-info")`](https://github.com/gradlex-org/extra-java-module-info)
Only if your (existing) project cannot avoid using non-module legacy Jars[Here is a sample](https://github.com/gradlex-org/java-module-testing/tree/main/samples/use-all-java-module-plugins)
that shows all plugins in combination.[In episodes 31, 32, 33 of Understanding Gradle](https://github.com/jjohannes/understanding-gradle) I explain what these plugins do and why they are needed.
[](https://www.youtube.com/watch?v=X9u1taDwLSA&list=PLWQK2ZdV4Yl2k2OmC_gsjDpdIBTN0qqkE)
[](https://www.youtube.com/watch?v=T9U0BOlVc-c&list=PLWQK2ZdV4Yl2k2OmC_gsjDpdIBTN0qqkE)
[](https://www.youtube.com/watch?v=6rFEDcP8Noc&list=PLWQK2ZdV4Yl2k2OmC_gsjDpdIBTN0qqkE)
[Full Java Module System Project Setup](https://github.com/jjohannes/gradle-project-setup-howto/tree/java_module_system) is a full-fledged Java Module System project setup using these plugins.
[](https://www.youtube.com/watch?v=uRieSnovlVc&list=PLWQK2ZdV4Yl2k2OmC_gsjDpdIBTN0qqkE)
# How to use?
For a quick start, you can find some samples here:
* [samples/use-all-java-module-plugins](samples/use-all-java-module-plugins)
* [samples/use-only-java-module-testing-plugin](samples/use-only-java-module-testing-plugin)
* [samples/use-with-test-fixtures](samples/use-with-test-fixtures)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](https://www.youtube.com/playlist?list=PLWQK2ZdV4Yl2k2OmC_gsjDpdIBTN0qqkE).## 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.6")
}
```## 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](https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html) into _Blackbox Test Suites_ if the `src//module-info.java` file exists.
A blackbox test suite is a separate module itself.
See documentation on [JVM Test Suites](https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html#sec:jvm_test_suite_configuration) for more details on creating and configuring test suites.## Whitebox Test Suites
The plugin automatically turns [JVM Test Suites](https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html) **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](https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html#sec:jvm_test_suite_configuration) 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 `/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](https://docs.gradle.org/current/userguide/java_testing.html#whitebox_unit_test_execution_on_the_classpath).
By default, this plugin replaces this with the [Whitebox Test Suite setup](#whitebox-test-suites), 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`):
- Normally, the test classes are loaded from a `classes` folder
- Now, the test classes are packaged into a module `jar` together with the test resources. Otherwise, test resources would not be visible to the test module at runtime.## Whitebox Test
Changes for test compilation (`:compileTestJava`):
- Normally, Gradle would not use the Module Path, as there is no `module-info.java` in the source set
- Now, a Module Path is computed for the compilation.
Using `--patch-module`, the test classes are compiled as an addition to the main module.Changes for test runtime (`:test`):
- Normally, Gradle would not run its test runner as Module, as there is no `module-info.class` as part of the compiled tests.
- Now, the main and test classes are both used as locations for test discovery.
By this, Gradle will find the `module-info.class` of the main module for the tests.
Using `--patch-module`, _main classes_, _main resources_, _test classes_, and _test resources_ folders are all merged to be treated as one module during test runtime.# 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.