代碼覆蓋率
在做單元測試時,代碼覆蓋率常常被拿來作為衡量測試好壞的指標,甚至,用代碼覆蓋率來考核測試任務完成情況,比如,代碼覆蓋率必須達到80%或 90%。
JaCoCo
Jacoco從多種角度對代碼進行了分析,包括指令(Instructions,C0 Coverage),分支(Branches,C1 Coverage),圈復雜度(Cyclomatic Complexity),行(Lines),方法(Methods),類(Classes)。
1. Instructions
Jacoco計算的最小單位就是字節(jié)碼指令。指令覆蓋率表明了在所有的指令中,哪些被指令過以及哪些沒有被執(zhí)行。這項指數(shù)完全獨立于源碼格式并且在任何情況下有效,不需要類文件的調(diào)試信息。
2. Branches
Jacoco對所有的if和switch指令計算了分支覆蓋率。這項指標會統(tǒng)計所有的分支數(shù)量,并同時支出哪些分支被執(zhí)行,哪些分支沒有被執(zhí)行。這項指標也在任何情況都有效。異常處理不考慮在分支范圍內(nèi)。
在有調(diào)試信息的情況下,分支點可以被映射到源碼中的每一行,并且被高亮表示。
紅色鉆石:無覆蓋,沒有分支被執(zhí)行。
黃色鉆石:部分覆蓋,部分分支被執(zhí)行。
綠色鉆石:全覆蓋,所有分支被執(zhí)行。
3. Cyclomatic Complexity
Jacoco為每個非抽象方法計算圈復雜度,并也會計算每個類,包,組的復雜度。根據(jù)McCabe1996的定義,圈復雜度可以理解為覆蓋所有的可能情況最少使用的測試用例數(shù)。這項參數(shù)也在任何情況下有效。
4. Lines
該項指數(shù)在有調(diào)試信息的情況下計算。因為每一行代碼可能會產(chǎn)生若干條字節(jié)碼指令,所以我們用三種不同狀態(tài)表示行覆蓋率
紅色背景:無覆蓋,該行的所有指令均無執(zhí)行。
黃色背景:部分覆蓋,該行部分指令被執(zhí)行。
綠色背景:全覆蓋,該行所有指令被執(zhí)行。
5. Methods
每一個非抽象方法都至少有一條指令。若一個方法至少被執(zhí)行了一條指令,就認為它被執(zhí)行過。因為JaCoco直接對字節(jié)碼進行操作,所以有些方法沒有在源碼顯示(比如某些構造方法和由編譯器自動生成的方法)也會被計入在內(nèi)。
6. Classes
每個類中只要有一個方法被執(zhí)行,這個類就被認定為被執(zhí)行。同5一樣,有些沒有在源碼聲明的方法被執(zhí)行,也認定該類被執(zhí)行。
JaCoCo原理
參考網(wǎng)址:http://www.open-open.com/lib/view/open1472174544246.html
其中包含了注入探針以及修改字節(jié)碼的相關原理。
與maven集成
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<configuration>
<destFile>target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
實例解析
在經(jīng)過與maven集成之后,生成的report文件在site/jacoco下,點開index.xml,即可查看生成報告。
包視圖:
類視圖:
方法視圖:
代碼視圖:
以上三個表每個表都包含了五項指標數(shù)據(jù)。
代碼視圖中,背景色代表的含義上文已經(jīng)提到。
寶石的顏色代表分支覆蓋率,鼠標移動到黃色寶石上,將會提示如“1 of 2 branches missed”,對于“name==null”,有true和false兩種分支,這說明程序只執(zhí)行了一種分支。綠色寶石“All 2 branches covered”。紅色寶石“All 2 branches missed”。