JaCoCo覆盖率计数器

覆盖率计数器

JaCoCo使用一组不一样的计数器来计算覆盖率指标。全部这些计数器都是从Java类文件里获取信息,这些类文件包含Java 字节码指令和调试信息。即便没有可用源代码状况下,这种方法能够实时有效的对应用程序进行检测和分析。在大多数状况下,收集的信息能够映射回源代码,并可视化到每一行代码的粒度。然而,这种方法也有局限性。这些类文件必须使用调试信息编译,这样才能够计算行的覆盖率并让源码高亮显示。并非全部的Java语言的结构均可以直接编译成相应的字节码。在这种状况下,Java编译器建立所谓的“合成”代码,有时会致使未预料到的代码覆盖结果。html

指令(C0 覆盖率)

JaCoCo最小的计数单元是单个Java字节代码指令。指令覆盖率提供了代码是否被执行的信息。这个度量是彻底独立于源格式而且常常可用,即便在类文件缺失调试信息的状况下。函数

分支(C1 覆盖率)

JaCoCo还计算全部的 if 和 switch 语句的分支覆盖率。这个度量计算一个方法里的总分支数并肯定执行或未执行的分支数。分支覆盖率老是可用的,即便类文件里缺失调试信息的状况下。请注意异常处理是不在分支度量里面统计的。单元测试

若是类文件使用调试信息编译,产生的覆盖率能够映射到源码行而且高亮显示:测试

  • 没有覆盖:行内没有分支被执行(红色代码块)
  • 部分覆盖:行内只有一部分分支被执行(黄色代码块)
  • 彻底覆盖:行内全部分支都被执行 (绿色代码块)

圈复杂度

JaCoCo一样能够为每个非抽象方法计算圈复杂度,最终计算出类、包、组的复杂度。根据McCabe1996圈复杂度的定义是,在线性组合中,计算在一个方法里面全部可能路径的最小数量。所以,复杂度的值能够做为表示单元测试用例是否有彻底覆盖全部场景的一个依据。复杂度数字即便在类文件缺失调试信息的状况下也能够计算。调试

圈复杂度 v(G) 的正式定义基于方法的控制流程图做为有向图的表示:htm

               v(G) = E - N + 2接口

其中,E表明边界的数量,N表示节点的数量。JaCoCo经过下面基于分支数量(B)和决策点数量(D)的等价方程来计算方法的圈复杂度:get

               v(G) = B - D + 1编译器

基于每一个分支的被覆盖状况,JaCoCo也为每一个方法计算覆盖率和缺失的复杂度。缺失的复杂度一样表示测试用例没有彻底覆盖到这个模块。值得注意的是JaCoCo并不会将异常处理做为分支, try/catch 块也一样不会增长复杂度。源码

全部的类文件使用调试信息编译以后,就能够计算行的覆盖率信息。一行源代码是否被执行,要看这一行中是否至少有一个指令被执行。因为单一行代码一般被编译为多个字节码指令,这样源码在高亮显示时,会显示成3种不一样的状态:

  • 没有覆盖:行中没有执行任何指令 (红色背景)
  • 部分覆盖:行中只有一部分指令被执行(黄色背景)
  • 彻底覆盖:行中的全部指令都已执行(绿色背景)

根据源代码格式的不一样,源代码的单行可能引用多个方法或多个类。所以,不能简单地添加方法的行计数来获取包含类的总数。同一个源文件中多个类的行也是如此。Jacoco根据覆盖的实际源行计算类和源文件的行覆盖率。

方法

每一个非抽象方法至少包含一个指令。一个方法是否执行取决于方法中是否至少有一个指令被执行。当Jacoco在字节代码级别上工做时,构造器和静态初始化一样会像方法同样统计。其中一些方法可能没有能够直接对应的Java源码,好比默认构造器或常量的初始化命令。

一个类是否执行取决于类中是否至少有一个方法被执行。值得注意的是JaCoCo认为构造函数和静态初始化都是方法。Java的接口通常包含静态初始化,因此接口也一样被认为是可执行的类。

相关文章
相关标签/搜索