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>
【讨论】:
这个依赖真的很麻烦。我已经有了这些排除。显式添加以下依赖项以升级 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 > Invalidate Cache > 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'”