Spring Boot 2.2 出现错误“带有 ID 'junit-vintage' 的 TestEngine 无法发现测试”

Posted

技术标签:

【中文标题】Spring Boot 2.2 出现错误“带有 ID \'junit-vintage\' 的 TestEngine 无法发现测试”【英文标题】:Error "TestEngine with ID 'junit-vintage' failed to discover tests" with Spring Boot 2.2Spring Boot 2.2 出现错误“带有 ID 'junit-vintage' 的 TestEngine 无法发现测试” 【发布时间】:2020-05-11 00:40:57 【问题描述】:

我有一个使用 Spring Boot 和 Junit 5 的简单应用:

当使用 Spring Boot 2.1(例如,2.1.8 或 2.1.12)时,我的单元测试运行 顺利

使用 Spring Boot 2.2(例如 2.2.2.RELEASE 或 2.3.2.RELEASE)时,我的单元测试失败并显示错误消息

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project XXX: There are test failures.
[ERROR]
[ERROR] Please refer to D:\Projets\workspace\XXX\target\surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] There was an error in the forked process
[ERROR] TestEngine with ID 'junit-vintage' failed to discover tests
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] TestEngine with ID 'junit-vintage' failed to discover tests
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:656)

我正在使用 Maven 3.6.1、JDK 1.8、JUnit 5.6.0 和 JUnit 平台 1.6.0。我从spring-boot-starter-test 中排除了对junit:junit 的依赖,因此我在依赖树中没有JUnit 4 工件。请注意,Spring Boot 2.2 和 2.3 都使用 maven-surefire-plugin 2.22.2,所以我的问题不是源自 maven-surefire-plugin 的任何回归。

我应该坚持使用 Spring Boot 2.1 以使我的单元测试正常工作吗?

提前感谢您的帮助。

【问题讨论】:

因为这意味着 mvn 使用了错误的 JDK 11,而不是 15 【参考方案1】:

我发现了错误。对spring-boot-starter-test 的依赖带来了对junit-vintage-engine 的依赖。后者必须排除:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

【讨论】:

这个依赖真的很麻烦。我已经有了这些排除。 junitjunitcom.vaadin.external.googleandroid-json 它有效!谢啦。有同样的问题!【参考方案2】:

显式添加以下依赖项以升级 junit-vintage-engine 解决了该问题:

<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.7.0</version>
</dependency>

【讨论】:

这解决了我的问题【参考方案3】:

在我的情况下(GRADLE 和 Spring Boot 2.x.x),添加排除老式工作

configurations 
    all 
        exclude(group = "junit", module = "junit")
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    

【讨论】:

【参考方案4】:

对于问题中报告的错误或以下错误,两者都与同一个问题有关。

java.lang.NoClassDefFoundError: junit/runner/Version

如果项目在依赖spring-boot-starter-test时排除或不包含JUnit 4,则会出现此错误。 spring-boot-starter-test 默认依赖于 junit-vintage-engine。要解决此问题,我们要么必须排除 junit-vintage-engine,要么不应该依赖 spring-boot-starter-test

    testImplementation('org.springframework.boot:spring-boot-starter-test:2.2.2.RELEASE') 
        exclude group: 'junit'
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    

    testImplementation('org.junit.jupiter:junit-jupiter-api:5.5.2')
    testImplementation('org.junit.jupiter:junit-jupiter-engine:5.5.2')
    testImplementation('org.junit.jupiter:junit-jupiter-params:5.5.2')

【讨论】:

我从 spring-boot-starter-test 依赖项中排除了“junit-vintage-engine”,但是测试甚至无法启动,只是在测试运行窗口中显示为灰色 @sunnyarya,请检查您的依赖关系树,并检查您的类路径中是否存在 'junit-vintage-engine' 模块,它对许多人来说是一个可行的解决方案,我不确定基于什么,答案是被否决【参考方案5】:

最好的选择是在启用调试的情况下运行 Maven 测试:

例如mvn clean test -X。它将显示确切的失败原因。

在我的例子中,我试图运行一些 Spock 测试,但没有找到所需的 Groovy XML 依赖项(参见下面的堆栈跟踪)。当我显式添加 Groovy 依赖时,它就解决了。

TestEngine with ID 'spock' failed to discover tests
org.junit.platform.commons.JUnitException: TestEngine with ID 'spock' 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: java.lang.NoClassDefFoundError: groovy/xml/MarkupBuilder
        at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
...

【讨论】:

我非常同意你的观点!就我而言,我还检查了来自surefire的转储文件,在那里我发现了另一个类的关于NoClassDefFoundError的臭名昭著的错误。你真的帮了我。【参考方案6】:

我也有这个问题。我尝试了上面提到的不同解决方案,但没有任何效果。真正起作用的是 Intellij 的简单而荒谬的重启。

【讨论】:

【参考方案7】:

我通过使用Maven dependency analyzer 并搜索“junit”修复了同样的错误。第一方依赖项(红色条)引入了 json-simple,它引入了 4.10 junit 依赖项。只需排除 4.10 junit(右键单击 + 排除)即可修复它。

【讨论】:

【参考方案8】:

排除依赖项不是我们的选择。因为这样我们就没有运行我们的测试了。 所以我们的解决方案是降级 JUnit 版本:

<!--
  junit-vintage-engine 5.5.2 version does not support junit 4.13.1.
  If we try to use it, a parsing error is thrown.
  So we downgrade JUnit, so that junit-vintage-engine will handle it.
-->
<version.legacy.junit>4.13</version.legacy.junit>

使用 Spring Boot 2.3.4 似乎可以正常工作。

【讨论】:

不幸的是,4.13.1 之前的 JUnit 版本存在安全漏洞:nvd.nist.gov/vuln/detail/CVE-2020-15250 不幸的是,如果我们尝试做相反的事情,升级junit-vintage-engine,我们会收到错误:``` bash [ERROR] TestEngine with ID 'junit-vintage' failed to discover tests ```所以这个安全漏洞似乎是我们目前所能拥有的最好的。 您需要使用 BOM junit-bom 我认为将您的所有 JUnit5 依赖项都升级到 5.7.0。如果你只使用 JUnit4,你也可以从 spring-boot-starter-test 中排除 junit-jupiter、junit-vintage-engine 和 mockito-junit-jupiter。 我们尝试过,但没有成功...如果您有兴趣,请参阅此处的讨论:github.com/hibernate/hibernate-search/pull/2409【参考方案9】:

在我的例子中,问题是通过使想法(IntelliJ)缓存无效来解决的。

File &gt; Invalidate Cache &gt; Invalidate and Restart

【讨论】:

【参考方案10】:

如果运行位于 java9 命名模块内的测试(也适用于 Spring Boot 应用程序),“junit-jupiter”测试引擎也会出现类似问题。消息相同,但不知道原因:

TestEngine with ID "junit-jupiter" failed to discover tests

在这种情况下的问题是,您的一个测试类需要命名为 java9 的模块,而您的 module-info.java 中不需要该模块。

要确认这一点,请转到该特定模块并使用 -X 选项执行构建以启用调试堆栈跟踪。之后,您将获得有关该问题的更详细信息:

    [ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process                                                                              
    [ERROR] TestEngine with ID 'junit-jupiter' failed to discover tests                                                                                                                         
    [ERROR] org.junit.platform.commons.JUnitException: TestEngine with ID 'junit-jupiter' failed to discover tests                                                                              
(...)                                                                                               
    [ERROR] Caused by: org.junit.platform.commons.JUnitException: ClassSelector [className = 'x.y.z.YourTest'] resolution failed                                                                                                                                                                  
    [ERROR]         at org.junit.platform.launcher.listeners.discovery.AbortOnFailureLauncherDiscoveryListener.selectorProcessed(AbortOnFailureLauncherDiscoveryListener.java:39)               
    (...)                                                                                                                                                 
    [ERROR] Caused by: java.lang.IllegalAccessError: class x.y.z.YourTest (in module com.your.module) cannot access class com.fasterxml.jackson.core.JsonProcessingException (in module com.fasterxml.jackson.core) because module com.bnymellon.rei.data.exchange.au
    th.service does not read module com.fasterxml.jackson.core   

正如消息所说,jackson.core 不可用,需要添加到您的模块描述符module-info.java

open module com.your.module 
 (...)
  requires com.fasterxml.jackson.core;
  requires com.fasterxml.jackson.databind;

                                                                                                                         

注意:在上面的示例中,您还可以看到 jackson.databind 添加为后续异常(在您重新运行 maven build 之后)很可能表明该异常也丢失了。

【讨论】:

【参考方案11】:

在我的 gradle 案例中,这个错误是由于有

testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$jUnitVersion"

而不是

testImplementation "org.junit.jupiter:junit-jupiter-engine:$jUnitVersion"

【讨论】:

【参考方案12】:

此错误消息的另一个原因可能是混合的 junit 版本集:

在不断地从 junit 5.6.2 切换到 5.7.2 后,为我修复了该错误。

【讨论】:

【参考方案13】:

在这种情况下解决我的问题的方法是更改​​ IntelliJ 的设置,以使用 Gradle 而不是 Intellij 作为 Gradle 构建器。

【讨论】:

【参考方案14】:

我的解决方案删除了​​以下依赖项:

<dependency>
    <groupId>junit-addons</groupId>
    <artifactId>junit-addons</artifactId>
    <scope>test</scope>
</dependency>

【讨论】:

【参考方案15】:

我的 pom 中已经排除了 junit-vintage-engine,但遇到了问题。是否使缓存无效并在 IntelliJ 中重新启动以使其工作。

【讨论】:

【参考方案16】:

对我来说,上面没有任何效果。但是,从 maven 添加最新版本的 JUnit 为我解决了这个问题。

【讨论】:

【参考方案17】:

如果有人仍然有这个问题,以上对我不起作用。我的解决方案涉及使用最新的 Spring Boot 测试依赖项,然后在 Spring Boot 测试注释中包含类名,如下所示。我删除了所有以前的 junit 排除项和显式依赖项。

@SpringBootTest(classes = testclass.class)

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <version>2.6.2</version>
    </dependency>

【讨论】:

【参考方案18】:

几个月前我在一个运行良好的项目中遇到了这种情况,但是当我返回时,单元测试不再在 IntelliJ 中运行。我重新启动了 IntelliJ,没有任何变化,更新了 IntelliJ 并且“Wala”错误消失了。

【讨论】:

似乎原始发布者找到了修复,与更新现有组件无关。您是对的,您看到的错误可能与原始问题中描述的相同,但该错误是一个非常普遍的错误,而不是一个强烈的信号。因此,您应该提供更多证据证明您的解决方案实际上与他/她的问题相关。

以上是关于Spring Boot 2.2 出现错误“带有 ID 'junit-vintage' 的 TestEngine 无法发现测试”的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.2 在请求“/*.jsp”时仍然显示白标签错误

spring-boot跟整合mapper出现如下错误,盼望高手解答

Spring @RestController,spring-boot 出现意外错误(类型=不可接受,状态=406)

Spring Boot + REST 应用程序出现“无可用消息”错误

带有 Spring Boot 应用程序的 Jetty 9.4.21 出现 TypeCast 错误

在 tomcat 9 上部署 Spring Boot Web 应用程序时,出现错误“无法检索系统属性'spring.xml.ignore'”