Jacoco的原理(各個覆蓋率的解釋)


覆蓋率計數器

Jacoco使用一系列的不同的計數器來做覆蓋率的度量計算。所有這些計數器都是從java的class文件中獲取信息,這些class文件可以(可選)包含調試的信息在里面。即使在沒有源碼的情況下,這種方法也可以實時有效地對應用程序進行度量和分析。在大部分情況下,收集到的信息可以映射到源碼,可視化到每一行代碼的粒度。但這種方法還是有一些限制。這些class文件必須使用調試信息來編譯,這樣才可以計算行的覆蓋率和提供出源碼的高亮。但不是所有的JAVA語言的結構都可以直接編譯成一致的二進制代碼。在這種情況下,java 編譯器會創建所謂的“合成”代碼,會導致產生一些不期望得到的覆蓋率結果。

指令(C0 Coverage)

Jacoco最小的計數單元是單個java二進制代碼指令。指令覆蓋率提供了代碼是否被執行的信息。這個度量完全獨立源碼格式,並且總是可用,即使class文件里面沒有調試信息。

分支(C1 Coverage)

Jacoco也計算分支的覆蓋率,包括所有的if和switch語句。這個度量計算一個方法里面的總分支數,確定執行和不執行的分支數量。分支覆蓋率總是可用的,即使class文件里面沒有調試信息。注意異常處理是不在分支度量里面統計的。

如果class文件使用調試信息編譯的話,產生的覆蓋率可以映射到源碼行並且高亮提示:

  • 沒有覆蓋:在這一行中沒有分支被執行(紅色方塊)
  • 部分覆蓋:這一行的分支中只有一部分被執行(黃色方塊)
  • 完全覆蓋:這一行的所有分支都被執行(綠色方塊)

圈復雜度

Jacoco同樣可以為每一個非抽象方法計算復雜度,最終計算出類、包和組的復雜度。根據由McCabe1996圈復雜度的定義是,在(線性)組合中,計算在一個方法里面所有可能路徑的最小數目。所以復雜度可以作為度量單元測試是否有完全覆蓋所有場景的一個依據。復雜度即使是在沒有調試信息的情況下也可以計算。

圈復雜度V(G)的正式定義是基於方法的控制流圖的有向圖表示:

v(G) = E – N + 2

E是邊界的數量,N是節點的數量。Jacoco 基於下面的方程來計算復雜度,B是分支的數量,D是決策點的數量:

v(G) = B – D + 1

基於每個分支的被覆蓋情況,Jacoco也為每個方法計算覆蓋和缺失的復雜度。缺失的復雜度同樣表示測試案例沒有完全覆蓋到這個模塊。注意Jacoco不將異常處理作為分支,try/catch塊也同樣不增加復雜度。

所有的class文件使用debug信息編譯之后,就可以計算行的覆蓋率信息。一行源代碼是否被執行,要看這一行中是否至少有一個指令被執行。

由於實際上一行代碼一般被編譯成多個二進制代碼指令,這樣源碼在高亮顯示時,會顯示成3種不同的狀態:

  • 沒有覆蓋:這一行中沒有指令被執行(紅色背景)
  • 部分覆蓋:這一行中只有一部分指令被執行(黃色背景)
  • 完全覆蓋:這一行中所有指令都被覆蓋(綠色背景

方法

每一個非抽象方法至少包含一個指令。一個方法是否執行取決於方法中是否有至少一個指令被執行。在Jacoco中,構造器和靜態初始化同樣會像方法一樣統計。其中一些方法可能沒有可以直接對應的源碼,比如默認構造器或常量的初始化命令。

一個方法是否執行取決於類中是否有至少一個方法被執行。注意Jacoco認為構造器和靜態初始化都是方法。Java的接口一般包含靜態初始化,所以接口也同樣被認為是可執行的類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM