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

时间:2013-03-06 19:04:02

标签: java code-coverage cobertura jacoco clover

This sonar page基本上列出了不同代码覆盖率分析工具采用的各种方法:

  1. 源代码检测(由Clover使用)
  2. 离线字节码检测(由Cobertura使用)
  3. 动态字节码检测(由Jacoco使用)
  4. 这三种方法是什么,哪种方法效率最高?为什么?如果效率问题的答案是“依赖”,请解释原因?

2 个答案:

答案 0 :(得分:14)

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

离线字节码检测包括添加相同的指令,但在编译之后,直接添加到字节码中。

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

This page对方法进行了比较。它可能有偏见,因为它是Clover文档的一部分。

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

答案 1 :(得分:3)

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

源代码检测可以提供更好的报告结果,原因很简单,因为字节码检测无法区分源代码行中的任何结构,因为代码块粒度只按源代码行记录。

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

你可能会认为这是一种罕见的情况(可能是这样),因此不是很有用。当你得到虚假的报道然后是现场失败时,你可能会改变你对实用性的看法。

有一个 nice example and explanation of how byte code coverage makes getting coverage of switch statements right,非常困难。

源代码指导程序也可以实现更快的测试执行,因为它有编译器帮助优化已检测的代码。特别是,由二进制指令器插入循环内的探测器可能会被JIT编译器编译到循环内部。一个好的Java编译器会看到检测产生一个循环不变的结果,并将检测提升出循环。 (JIT编译器也可以说这样做;问题是它们是否真的这样做了。)