未引入JUnit Vintage Engine时Surefire仍执行JUnit4测试原因咨询
原因说明
3.0.0-M07版本的Maven Surefire插件内置了独立的多测试框架自动识别、分链路执行逻辑,该场景下不需要依赖JUnit Vintage Engine就能运行JUnit4测试用例,核心逻辑如下:
- 从3.0.0-M5版本开始,Surefire重构了测试提供者加载机制:插件会独立扫描测试classpath下的测试框架依赖,匹配到对应框架后直接调用框架原生的执行入口跑用例,不需要全部走JUnit 5的JUnit Platform统一链路。
- 你的依赖里同时存在JUnit Jupiter(JUnit5核心)和JUnit4的原生核心依赖,插件会分别启动两套独立执行链路:检测到
org.junit.jupiter相关依赖时,调用Jupiter执行器运行JUnit5用例;检测到junit:junit依赖时,直接调用JUnit4原生执行器运行JUnit4用例,两个执行过程互不依赖。 - JUnit 5官方文档提到的「必须引入JUnit Vintage Engine才能运行JUnit4测试」,有明确的前提:所有测试都要通过JUnit Platform(JUnit5的统一运行基座)执行。Vintage Engine本质是个桥接组件,作用是把JUnit4的用例包装成JUnit Platform可识别的测试节点,只有走JUnit Platform统一执行链路的时候才需要这个组件。你的场景里JUnit4用例根本没走JUnit Platform链路,自然不需要这个依赖。
你可以通过两个简单操作验证这个逻辑:
- 将Surefire插件版本降级到2.22.x系列,同时保持不引入JUnit Vintage Engine依赖,执行测试就会发现JUnit4用例无法被识别执行——低版本Surefire没有独立的JUnit4原生执行适配,要么走JUnit4老执行逻辑、要么走JUnit Platform链路,当classpath下同时存在JUnit4和JUnit5依赖时会优先走JUnit Platform链路,缺Vintage Engine就跑不了JUnit4用例。
- 把项目里的
junit:junit:4.13.2依赖排除,保持其他配置不变,再执行测试就会发现JUnit4用例直接运行失败,证明当前JUnit4用例的执行确实依托原生JUnit4依赖,和Vintage Engine无关。
补充说明:如果你需要实现JUnit4和JUnit5用例共享JUnit Platform扩展、统一测试监听、跨框架用例过滤等能力,还是需要显式引入JUnit Vintage Engine,把所有用例都收敛到JUnit Platform统一链路上执行,Surefire原生分链路执行的模式不支持这类跨框架的Platform级特性。
内容的提问来源于stack exchange,提问作者Harold L. Brown
相关产品推荐
相关产品推荐

