I am trying to figure out how to create the equivalent of a JUnit4 test case suite in JUnit Jupiter, using Eclipse.
For example, let's say I have the following Test Case Suite in JUnit 4:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
CoreContentFactoryTest.class,
DatatypesFactoryTest.class,
SpecifiedValuesFactoryTest.class,
EmbeddedValueFactoryTest.class,
DefinitionFactoryTest.class
})
public class TestCaseSuite {
}
Assuming all the tests are ported to JUnit Jupiter, how do I create the equivalent suite in JUnit Jupiter?
I have tried the following, where datatypes
is the package containing the above classes:
import org.junit.platform.runner. JUnitPlatform;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.SuiteDisplayName;
import org.junit.runner.RunWith;
@RunWith(JUnitPlatform.class)
@SuiteDisplayName("Datatype Test Cases")
@SelectPackages({
"datatypes"
})
public class TestCaseSuite {
}
However, when I try to run this the same way I run the JUnit4 Test Case Suite (by saying "Run as JUnit Test"), I get the following error message:
java.lang.NoSuchMethodError: org.junit.runner.Description.createSuiteDescription(Ljava/lang/String;Ljava/io/Serializable;[Ljava/lang/annotation/Annotation;)Lorg/junit/runner/Description;
at org.junit.platform.runner.JUnitPlatformTestTree.createJUnit4Description(JUnitPlatformTestTree.java:108)
at org.junit.platform.runner.JUnitPlatformTestTree.buildDescription(JUnitPlatformTestTree.java:95)
at org.junit.platform.runner.JUnitPlatformTestTree.lambda$buildDescriptionTree$0(JUnitPlatformTestTree.java:86)
at java.lang.Iterable.forEach(Unknown Source)
at java.util.Collections$SynchronizedCollection.forEach(Unknown Source)
at java.util.Collections$UnmodifiableCollection.forEach(Unknown Source)
at org.junit.platform.runner.JUnitPlatformTestTree.buildDescriptionTree(JUnitPlatformTestTree.java:86)
at org.junit.platform.runner.JUnitPlatformTestTree.generateSuiteDescription(JUnitPlatformTestTree.java:72)
at org.junit.platform.runner.JUnitPlatformTestTree.<init>(JUnitPlatformTestTree.java:50)
at org.junit.platform.runner.JUnitPlatform.generateTestTree(JUnitPlatform.java:144)
at org.junit.platform.runner.JUnitPlatform.<init>(JUnitPlatform.java:129)
at org.junit.platform.runner.JUnitPlatform.<init>(JUnitPlatform.java:122)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:90)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:76)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:49)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:526)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
What am I doing wrong here? using JUnit 4 this works fine.
EDIT:
I looked deeper into this and wanted to add this interesting piece: I can actually import org.junit.runner.Description
, which works fine, and then call the createSuiteDescription
method just fine, so how can this error even be? Apparently, the method is for some reason called with parameters of the wrong type. The function signature is:
public static Description createSuiteDescription(String name, Annotation... annotations)
But according to the error message, it is called with the following parameters:
createSuiteDescription(Ljava/lang/String;Ljava/io/Serializable;[Ljava/lang/annotation/Annotation;)
This is apprently caleld in the external class JUnitPlatformTestTree.java:108
. Could these be incompatible versions? And if so, what are compatible versions.
However checking the faulting line in the JUnitPlatformTestTree.java, it seems like the function is called with the correct parameters there:
return Description.createSuiteDescription(name, identifier.getUniqueId());
I am using the following gradle imports:
testCompile('org.junit.jupiter:junit-jupiter:5.6.0')
testCompile('org.junit.platform:junit-platform-runner:1.6.0')
testCompile('org.junit.platform:junit-platform-suite-api:1.6.0')
testCompile('org.junit.platform:junit-platform-launcher:1.6.0')
testCompile('org.junit.platform:junit-platform-engine:1.6.0')
testCompile('org.junit.platform:junit-platform-commons:1.6.0')
testImplementation 'junit:junit:4.12'
EDIT 2:
Okay, I tracked this down further, and found out that in gradle, we have the following dependency that when imported seems to ruin everything:
compile 'com.googlecode.json-simple:json-simple:1.1.1'
If I comment out that dependency, the error in the test case suite disappears. However, since the project needs JSONObject and JSONArray from json.simple, large parts of the project stop working.
This seems like an incompatability error. What causes this, and how can I work around it?