IntelliJ代码覆盖率报告不一致及异常分支覆盖率问题求助
我最近碰到一个特别诡异的IntelliJ代码覆盖率问题,翻遍了各种地方都没找到类似的情况。我们项目里某个包下的几个类,手动单独跑对应的测试类时,覆盖率报告显示100%;但跑整个包的测试时,这些类的覆盖率就会大幅下降(不是0%),而且明明对应的测试类已经被正常执行了。举个具体的例子:单独跑com.example.wtf.FooTest时,com.example.wtf.Foo的覆盖率是100%;但跑整个com.example.wtf包的测试时,Foo的覆盖率就变成47%了,而且能明确看到FooTest确实被执行了。我试过mvn clean、删除所有运行配置,甚至手动复制测试类(比如把FooTest复制成FooTest2),这些操作都没能解决问题。
另外,分支覆盖率也有点不对劲,看起来完全随机的代码行居然显示超高的分支数,比如一行return this;居然被报告为8/10分支覆盖。这两个问题都是在一次比较复杂的重构过程中出现的,我怀疑它们之间有关联,但也可能只是巧合。
我们项目的环境是:Maven、Java 23(未启用预览特性)、JUnit5。没用到什么特别冷门的功能,只是用了几次MockitoExtension,没有其他扩展;所有@ParameterizedTest用的都是标准测试数据源。我真的完全搞不懂是什么导致覆盖率报告出现这种异常。
相关代码示例
为了方便大家理解,我把几个类的无关细节(主要是名称)去掉了:
第一个类的结构如下:
@Service class FooFactory extends MemberHandler implements Supplier<Foo> { // 父类实现了InvocationHandler,并且自动注入了几个依赖 private final Foo proxy = createProxy(); @Override public Foo get() { return proxy; } private Foo createProxy() { return (Foo) newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, this); } }
单独跑FooHandlerTest时,所有代码都被标记为已覆盖;但跑包测试时,只有createProxy方法被标记为已覆盖。
第二个类的结构是这样的:
@Service class BarService implements Function<List<Foo>, Bar> { Bar apply(Foo... foos) { return apply(List.of(foos)); } @Override public Bar apply(List<Foo> foos) { // ... } }
跑包测试时,第一个apply方法显示已覆盖,但第二个(实现接口的那个)却没有;同样,单独跑BarServiceTest时覆盖率显示是完全正常的。
备注:内容来源于stack exchange,提问作者naomimyselfandi

