farmlandbee
farmlandbee

Reputation: 415

TestEngine with ID 'junit-jupiter' failed to discover tests - Caused by: org.junit.platform.commons.JUnitException: ClassSelector resolution failed

I am having an issue running my Integration Test.

As part of my Test, I use exec-maven-plugin to pull down other projects from source control and then run them locally so my Test can use that to perform against.

My Maven dependencies for JUnit are:

<plugins>
    <plugin>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.0.0-M5</version>
        <configuration>
            <useModulePath>false</useModulePath>
            <useSystemClassLoader>false</useSystemClassLoader>
            <skipTests>false</skipTests>
            <includes>
                <include>**/*IntegrationTest.java</include>
            </includes>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>
...
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.4.2</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

I have created a profile called integration-test so that I can choose when to enable integration testing and also added an argument to maven-surefire-plugin called skipUTs so I can skip Unit Tests.

The output of running: mvn clean verify -Pintegration-test -DskipUTs=true

org.junit.platform.commons.JUnitException: TestEngine with ID 'junit-jupiter' failed to discover tests
    at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:111)
    at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:85)
    at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:92)
    at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:67)
    at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:56)
    at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:102)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:147)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:128)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
Caused by: org.junit.platform.commons.JUnitException: ClassSelector [className = 'com.farmlandbee.app.integration.IntegrationTest'] resolution failed
    at org.junit.platform.launcher.listeners.discovery.AbortOnFailureLauncherDiscoveryListener.selectorProcessed(AbortOnFailureLauncherDiscoveryListener.java:39)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:102)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:82)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
    at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:45)
    at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:69)
    at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:103)
    ... 11 more
Caused by: java.lang.ArrayStoreException
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
    at java.lang.Class.getAnnotationCache(Class.java:2535)
    at java.lang.Class.getDeclaredAnnotation(Class.java:2221)
    at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:128)
    at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:115)
    at org.junit.jupiter.engine.descriptor.DisplayNameUtils.determineDisplayName(DisplayNameUtils.java:68)
    at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.<init>(JupiterTestDescriptor.java:69)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.<init>(ClassBasedTestDescriptor.java:94)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.<init>(ClassTestDescriptor.java:51)
    at org.junit.jupiter.engine.discovery.ClassSelectorResolver.newClassTestDescriptor(ClassSelectorResolver.java:119)
    at org.junit.jupiter.engine.discovery.ClassSelectorResolver.lambda$resolve$0(ClassSelectorResolver.java:71)
    at org.junit.jupiter.engine.discovery.ClassSelectorResolver$$Lambda$61/0000000000000000.apply(Unknown Source)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$DefaultContext.createAndAdd(EngineDiscoveryRequestResolution.java:246)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$DefaultContext.addToParent(EngineDiscoveryRequestResolution.java:209)
    at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:71)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:134)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$$Lambda$47/0000000000000000.apply(Unknown Source)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:514)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:501)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:487)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:241)
    at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:531)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:185)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:125)
    at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:91)
    ... 16 more

Test Class is roughly:

@SpringBootTest(classes = Application.class,
        webEnvironment = WebEnvironment.RANDOM_PORT)
@Import({SSLRestTemplateConfig.class})
@ExtendWith(SpringExtension.class)
@ActiveProfiles(profiles = {"integration"})
public class IntegrationTest {

    @LocalServerPort
    private int port;

    private final RestTemplate restTemplate;

    @Spy
    private final Service Service;

    private final IQueue<String> queue;

    @Captor
    ArgumentCaptor<String> captor;

    @Autowired
    public IntegrationTest(RestTemplate restTemplate,
                                Service service,
                                HazelcastInstance hazelcastInstance) {
        this.restTemplate = restTemplate;
        this.service = accountingQueueService;
        this.queue = hazelcastInstance.getQueue("queue");
    }

    @BeforeEach
    public void setup() {
        queue.clear();
    }

    @Test
    public void IntegrationTest() throws InterruptedException {
        ...
    }

}

Any help would be greatly appreciated.

Upvotes: 21

Views: 45071

Answers (6)

Abbas Gadhia
Abbas Gadhia

Reputation: 15090

This issue is usually when the classpath contains multiple versions of junit

for ex. org.junit.jupiter:junit-jupiter:5.8.2 and org.junit.jupiter:junit-jupiter-engine:5.9.0 both of which are incompatible with one another.

or for ex. both junit4 and junit5 libraries are on the classpath together.

To check if this is the case, do a gradlew dependecies --configuration testCompileClasspath (if you are using gradle. maven would have something similar) to check the dependency tree for multiple versions.

Sometimes, spring boot might be interfering using its dependency management plugin. The way it messes up is it fixes the version of junit in the dependency tree, no matter what version you have declared. So you might have one of the junit jars declared explicitly with one version and spring will be pulling another version.

Either ways, the dependency tree is the best way to find the problem. Once you get the version to be in sync, and everything will be fine.

Upvotes: 1

Roger C S Wernersson
Roger C S Wernersson

Reputation: 6562

I had this problem too. I solved it by removing all JUnit libraries from IntelliJ / Project Structure / Libraries, and then compiling the project, failing, having IntelliJ resolve this by importing the latest version of JUnit.

I'm now on JUnit 5.9.1

I believe the culprit was junit-platform-commons which is now on 1.9.1

I got the idea from this JUnit 5 issue: https://github.com/junit-team/junit5/issues/2881

Upvotes: 12

nitzv26
nitzv26

Reputation: 1

Basically, you need to ensure that the dependency version that you are using is compatible with the Java version that you are using. I was getting the same error. I had updated the junit-jupiter to 5.9.0 but I was using Java 11 due to which I was getting this error. On changing Java version to Java 17, the tests started running.

Upvotes: -2

Yinlei Chai
Yinlei Chai

Reputation: 1

i think the best way is to click File->InvalidateCaches/Restart...

Upvotes: 0

Atmas
Atmas

Reputation: 2393

I believe the problem would lie in one of the following areas. I don't think there's enough information to nail it down, but I wanted to give you all the avenues to explore and it's too much to put in one big comment.

I have listed them in order of complexity.

  1. You haven't set up your custom integration tests fully

There is information relevant that may help you configure your profiles and utilize them here: Spring-boot default profile for integration tests

  1. The @ActiveProfiles indicates a profile name of "integration" but your profile name is "integration-test"

If this is it, then just update the annotation to be integration-test and you're done.

  1. The configuration of one of your annotations is incorrect or the classpath is incorrectly setup to allow the annotation to be recognized.

I am not familiar with how a display name generator is chosen, but there is one line that stands out to me as the closest complaining point to review. The line in the stack trace is: org.junit.jupiter.engine.descriptor.DisplayNameUtils.determineDisplayName(DisplayNameUtils.java:68)

I believe this is the correct code that backs this line: http://www.howsoftworks.net/junjupen/DisplayNameUtils#determineDisplayName-AnnotatedElement-Supplier

It appears to be evaluating the entire class for annotations to try to pull back this one. However, above you have no DisplayName annotation configured, so I don't think it's a problem with DisplayName, but with one of the others.

Looking further in the stack, it looks like it's attempting to utilize/cache the Annotations of the class itself. This may lead to the annotations cache evaluating ALL entries on the class at this point and displayName is just the first one being requested.

In that case, it's possible it's tripping up on one of your OTHER annotations that you simply haven't configured correctly. ArrayStore exception makes me wonder if you've put an element where an array should be or vice-versa.

However, researching further, it looks like this error (line 724 in AnnotationParser) relates to a suite of JDK issues that were properly fixed in one of the JDK-11 releases. It is indicated in other places as a "sun.reflect.annotation.TypeNotPresentExceptionProxy".

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-7183985

The gist of these bugs have to do with an Annotation referencing a class that's not in the classpath (the Type is not present). This is probably what's going on with one of your annotations in your configuration but from the posted information it's unlikely we can advise which one.

Upgrading to a JDK where this is fixed would likely help you better pinpoint the root problem by reporting a better error for you with specific missing type information. If that's an option, you can choose to do that, too.

The root problem is likely that your new profile environment leads to a misconfiguration that's accidentally excluding a class that you need for the annotations on your test to be coherent.

Upvotes: 4

Alejandro Venegas
Alejandro Venegas

Reputation: 249

Try to pass the profile via command like this :

mvn clean verify -Dspring.profiles.active=integration-test

Upvotes: 1

Related Questions