測試覆蓋率工具之--01 Jacoco簡介
1. 測試覆蓋率工具
測試過程中根據需求文件和設計文件編寫測試用例、執行測試;為了更加全面的覆蓋,我們可能還需要理解被測程式的邏輯,需要考慮到每個函式的輸入與輸出,邏輯分支程式碼的執行情況,這個時候我們的測試執行情況就以程式碼覆蓋率來衡量。
覆蓋率是衡量測試效果的一個輔助指標。
1.1. 意義
- 分析未覆蓋部分的程式碼,從而反推在前期測試設計是否充分,沒有覆蓋到的程式碼是否是測試設計的盲點,為什麼沒有考慮到?需求/設計不夠清晰,測試設計的理解有誤,工程方法應用後的造成的策略性放棄等等,之後進行補充測試用例設計。
- 檢測出程式中的廢程式碼,可以逆向反推在程式碼設計中思維混亂點,提醒設計/開發人員理清程式碼邏輯關係,提升程式碼質量。
- 程式碼覆蓋率高不能說明程式碼質量高,但是反過來看,程式碼覆蓋率低,程式碼質量不會高到哪裡去,可以作為測試自我審視的重要工具之一。
1.2. 工具比較
市場上主流工具Emma,Cobertura,Jacoco,Clover(商用)
2. Jacoco簡介
Jacoco 是一個開源的覆蓋率工具,針對的語言為java。它可以嵌入到 Ant 、Maven 中,也提供了 EclEmma Eclipse 外掛。Jacoco 主要通過程式碼注入(即 Java Agent)方式來實現覆蓋率的功能。很多第三方的工具提供了對 Jacoco 的整合,如:Sonar、Jenkins、IDEA.
下載
2.1. 相關概念
jacoco支援多種覆蓋率的統計,包括:
- 行覆蓋率(Lines):度量被測程式的每行程式碼是否被執行,判斷標準行中是否至少有一個指令被執行。
- 類覆蓋率(classes)):度量計算class類檔案是否被執行。
- 分支覆蓋率(Branches,C1coverage):度量if和switch語句的分支覆蓋情況,計算一個方法裡面的總分支數,確定執行和不執行的 分支數量。
- 方法覆蓋率(non-abstract methods):度量被測程式的方法執行情況,是否執行取決於方法中是否有至少一個指令被執行。
- 指令覆蓋(Instructions,C0coverage):計數單元是單個java二進位制程式碼指令,指令覆蓋率提供了程式碼是否被執行的資訊,度量完全 獨立原始碼格式。
- 圈複雜度(CyclomaticComplexity):在(線性)組合中,計算在一個方法裡面所有可能路徑的最小數目,缺失的複雜度同樣表示測 試案例沒有完全覆蓋到這個模組。
2.2. 工作步驟
- 對Java位元組碼進行插樁,有on-the-fly和offline兩種方式。
- 執行測試用例,收集程式執行軌跡資訊,支援通過dump將操作記錄從服務端傳輸到本地。
- 資料處理器結合程式執行軌跡資訊和程式碼結構資訊分析生成程式碼覆蓋率報告。
- 結合原始碼和編譯後的檔案,可以將程式碼覆蓋率報告圖形化展示出來,如html,xml等檔案格式。
2.3. 插樁及不同插樁模式
2.3.1. 什麼是插樁
程式插樁,最早是由J.C. Huang 教授提出的,它是在保證被測程式原有邏輯完整性的基礎上在程式中插入一些探針(又稱為“探測儀”,本質上就是進行資訊採集的程式碼段,可以是賦值語句或採集覆蓋資訊的函式呼叫),通過探針的執行並丟擲程式執行的特徵資料,通過對這些資料的分析,可以獲得程式的控制流和資料流資訊,進而得到邏輯覆蓋等動態資訊,從而實現測試目的的方法。
2.3.2. On-The-Fly和Offine比較
On-The-Fly模式更加方便的獲取程式碼覆蓋率,無需提前進行位元組碼插樁,只需要JAVA_OPTS中增加 -javaagent 引數,該引數會被 AgentOptions 的 getVMArgument 方法載入。引數重製定 jacocoAgent.jar 檔案,就可以在程式啟動時啟動Instrumentation 的代理程式,代理程式再通過 Class Loader 裝載 class 前判斷是否轉換修改 class 檔案並將探針插入 class 檔案,探針不改變原來方法的行為,只是記錄程式碼行是否已經執行。
Offline模式適用於以下場景:
- 執行環境不支援java agent
- 部署環境不允許設定JVM引數
- 位元組碼需要被轉換成其他虛擬機器位元組碼,如Android Dalvik VM
- 動態修改位元組碼過程中和其他agent衝突
- 無法自定義使用者載入類