【问题标题】:What are the differences between the three methods of code coverage analysis?三种代码覆盖率分析方法有什么区别?
【发布时间】:2013-02-21 17:49:38
【问题描述】:

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

  1. 源代码检测(供Clover使用)
  2. 离线字节码检测(供Cobertura使用)
  3. 动态字节码检测(供Jacoco使用)

这三种方法是什么,哪一种效率最高,为什么?如果效率问题的答案是“取决于”,请解释为什么?

【问题讨论】:

    标签: java code-coverage cobertura jacoco clover


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 我想你想要一个 Clover 文档的链接?
    • 是的。我忘了添加链接。现在完成。感谢您发现问题。
    • 目前 cobertura 同时支持 Java 7 和 Java 8
    • 但没有使用仪器,这意味着我们已经构建了包括仪器打印和另一个用于操作的构建(不打印)。所以总有人可以说,测试是在不同的版本上完成的,对吧?
    【解决方案2】:

    通常对覆盖率的影响是相同的。

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

    假设我在一行中有两个嵌套的 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 编译器也可以这样做;问题是他们是否真的这样做)。

    【讨论】:

    • 实际上,像 Cobertura 和 JaCoCo 这样的工具没有显示行内覆盖信息的原因仅仅是开发人员选择不实现它。在我自己的即时字节码检测工具 (JMockit Coverage) 中,此 实现并且单独的线段(例如在“if (a && b)”中) 显示为覆盖率报告中的内容。
    • 这就是所有工具的方式:“开发人员选择不实现(某些功能)”。好在你有更多的热情。你如何区分线路的各个部分?我认为类文件没有提供任何更详细的信息。
    • 在字节码层面,跳转指令是在一行代码中分离多个可执行段的基础。每个跳转指令都有一个目标指令,它可能在也可能不在同一行;此信息由用于字节码操作的 ASM 库提供。对于每一行代码,都会保留一个跳转指令及其目标的列表,并在稍后提供给 HTML 报告生成器,然后在匹配字节码分支的同时解析每一行 source 代码到单个线段。
    • @Rogério:实施起来一定很有趣。面对代码优化/简化和代码运动,这如何发挥作用? (另一位用户报告说,编译器忽略了“x==null”的条件测试,如果它在评估条件“x==null”时知道“x!=null”为真。你如何匹配事情可靠吗?)
    • 我没有遇到任何这样的困难仅仅是因为没有在字节码级别进行优化/简化; Java 编译器生成标准化和未优化的字节码(javac 和 Eclipse 编译器之间有一些细微差别),而这(加上源代码)是覆盖工具需要使用的全部内容。 JIT 优化不会干扰。我认为“其他用户”是错误的;如果源中存在“x==null”条件,它将始终存在于字节码中。
    猜你喜欢
    • 2013-03-08
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    相关资源
    最近更新 更多