代码覆盖率分析的三种方法有什么区别?

2022-09-02 13:32:27

此声纳页面基本上列出了不同代码覆盖率分析工具采用的各种方法:

  1. 源代码工具(由三叶草使用))
  2. 离线字节码检测(由 Cobertura 使用))
  3. 动态字节码检测(由 Jacoco 使用))

这三种方法是什么,哪一种最有效,为什么?如果效率问题的答案是“视情况而定”,那么请解释一下为什么?


答案 1

源代码检测包括在编译源代码之前向源代码添加指令。这些指令用于跟踪已执行代码的哪些部分。

脱机字节码检测包括添加这些相同的指令,但在编译后,直接添加到字节码中。

动态字节码检测包括在字节码中添加这些相同的指令,但在运行时,当 JVM 加载字节码时,动态添加。

此页面比较了这些方法。它可能是有偏见的,因为它是三叶草文档的一部分。

根据您对“高效”的定义,选择您最喜欢的一个。我不认为你会得到巨大的差异。他们都做了这项工作,无论使用何种方法,大局都是一样的。


答案 2

一般来说,对覆盖范围的影响是相同的。

源代码检测可以提供出色的报告结果,这仅仅是因为字节码检测无法区分源代码行中的任何结构,因为代码块粒度仅以源代码行的形式记录。

想象一下,我在一行中有两个嵌套的if语句(或者等效地,if(a&b)...*)。源代码检测器可以看到这些,并为if内的多个臂提供覆盖信息,在源代码行内;它可以根据线条和列报告块。字节代码检测器只能看到一行环绕条件。如果条件 a 执行,它是否将行报告为“已覆盖”,但是否为 false?

你可能会争辩说这是一种罕见的情况(它可能是),因此不是很有用。当您获得虚假的报道后出现现场故障时,您可能会改变对效用的看法。

有一个很好的例子和解释,说明字节代码覆盖率如何使正确覆盖switch语句变得非常困难。

源代码检测器还可以实现更快的测试执行,因为它具有编译器帮助优化检测的代码。特别是,由二进制仪器器插入循环内的探测器可能由 JIT 编译器在循环内编译。一个好的Java编译器会看到检测产生循环不变的结果,并将检测从循环中移除。(JIT编译器也可以这么说;问题是他们是否真的这样做了)。


推荐