I would like to create a JUnit test using JUnit 5 in Eclipse (Oxygen 4.7.1a). This JUnit test should be inside a seperate src folder called Test. However, I ran into the following problems as I'm new to JUnit and Java 9.
I do not want to use build tools like Gradle or Maven for this.
As I've got two different src folders, one for the projects src and one for the test cases:
Please note that JUnit 5 requires minimum Java 8 at runtime.
It's important, however, to understand that the two terms are not the same. JUnit Jupiter is the API for writing tests using JUnit version 5. JUnit 5 is the project name (and version) that includes the separation of concerns reflected in all three major modules: JUnit Jupiter, JUnit Platform, and JUnit Vintage.
Creating Test Suites Creating suites is easy. Just add the @Suite annotation of a class and start including or excluding the test classes and methods into the suite. When we want to run the suite, simply run it as a normal JUnit test class and it will execute all the included tests in the suite.
Please note that JUnit 5 is not backward compatible with JUnit 4, but the JUnit team created the JUnit Vintage Project to support JUnit 4 test cases on top of JUnit 5.
In general there is no need to modularize your test code (at least I can't think of a valid reason, maybe someone could give a satisfactory counter-example). Only one module-info.java
file can (after all, it's not even required to modularize your main code) be present in your main code under src
.
Since the module-info.java
file will be only in your main source directory and not in the test source directory, then logically it should not depend on the JUnit module. So the questions now become how to compile and run the JUnit test classes by relying on the module (that represents the system under test) and the JUnit module.
To do that, you'll need to use the new options provided by the javac
and java
:
So assuming you have the following tree:
src
module-info.java (declares a module called "my.module")
mypackage
MyClass.java
test_src
mypackage
MyClassTest.java
lib/junit-platform-console-standalone.jar
(note: specifically for JUnit 5, you can use the junit-platform-console-standalone artifact that contains the core JUnit engine and allows running tests in the console; see the user guide)
then you can compile the code as follows:
cd root_dir
javac -d mods/my.module src/module-info.java src/mypackage/MyClass.java
cd test_src
javac -d test_out --module-path ../mods;../lib/junit-platform-console-standalone.jar \
--add-modules org.junit.platform.console.standalone,my.module --patch-module my.module=. \
--add-reads my.module=org.junit.platform.console.standalone mypackage/MyClass.java
and you can run the compiled test class:
cd test_src/test_out
java --module-path=../../mods;../../lib/junit-platform-console-standalone.jar \
--add-modules my.module,org.junit.platform.console.standalone \
--add-reads my.module=org.junit.platform.console.standalone \
--patch-module my.module=. \
--add-opens my.module/test=org.junit.platform.console.standalone \
org.junit.platform.console.ConsoleLauncher test.MyClassTest
Awkward commands but that's the cost of not using Maven. I advise you to read about these options in the command documentation after understanding the concept of a module path. An important thing to note here are a couple of options:
--patch-module my.module=.
This is needed because the example test code has the same package (mypackage
) as the module my.module
. Without it, the module system will complain.
--add-reads my.module=org.junit.platform.console.standalone
This makes junit required by my.module
even though it was not declared in module-info.java
.
org.junit.platform.console.standalone
is the name of the automatic module and is derived from the Jar manifest (as is the case with JUnit 5), otherwise from the name of the Jar file (e.g. in the case of JUnit 4).
Also note that this is what Maven probably does behind the scenes when compiling and running unit tests (see this issue for an equivalent plugin configuration that manually does the above).
What if for some reason, you also want to modularize your unit tests?
In this case, since in the example above the unit tests share the same package, you can include them in my.module
and add a requirement to JUnit:
module my.module {
exports mypackage;
requires org.junit.platform.console.standalone;
}
If the unit tests were in a different package, you can also split them into two modules (two module-info.java
), a my.module
and a my.test.module
where only the latter requires JUnit.
If you do include test classes in a module, then in the above commands, you don't need --add-reads
and --patch-module
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With