JAVA代碼覆蓋率工具JaCoCo-原理篇

分類:IT技術 時間:2016-10-14

總目錄

Java代碼覆蓋率工具JaCoCo-原理篇

1.2 JAVA覆蓋率工具介紹

1.3.3 Apache Maven方式

1.3.4 Eclipse EclDmma Plugin方式

JAVA代碼覆蓋率工具JaCoCo-實踐篇

一、覆蓋率項目中使用介紹

1.5執行測試,收集覆蓋率結果文件

1.5.1androidManifest文件的修改

1.5.2生成覆蓋率的apk工具和jacoco-cov-sdk.jar包

二、覆蓋率與BVT測試結合

2.1在BVT用例框架中插入覆蓋率方法

2.2執行BVT用例,得到覆蓋率

2.3批量生成覆蓋率報告,解析入庫

2.4分析覆蓋率結果,得出用例和代碼映射關系

三、差異覆蓋率和全量覆蓋率

JAVA代碼覆蓋率工具JaCoCo-踩坑篇

1.1 覆蓋率包在部分手機6.0上安裝失敗

1.2 覆蓋率包在部分4.X版本手機上生成ec文件失敗

1.3 覆蓋率報告生成後看不到源碼覆蓋情況

二、覆蓋率一些需要註意的地方

JAVA代碼覆蓋率工具JaCoCo-原理篇

1.1 覆蓋率定義

作為一個測試人員,保證產品的軟件質量是其工作首要目標,為了這個目標,測試人員常常會通過很多手段或工具來加以保證,覆蓋率就是其中一環比較重要的環節。

我們通常會將測試覆蓋率分為兩個部分,即“需求覆蓋率”和“代碼覆蓋率”。

需求覆蓋:指的是測試人員對需求的了解程度,根據需求的可測試性來拆分成各個子需求點,來編寫相應的測試用例,最終建立一個需求和用例的映射關系,以用例的測試結果來驗證需求的實現,可以理解為黑盒覆蓋。

代碼覆蓋:為了更加全面的覆蓋,我們可能還需要理解被測程序的邏輯,需要考慮到每個函數的輸入與輸出,邏輯分支代碼的執行情況,這個時候我們的測試執行情況就以代碼覆蓋率來衡量,可以理解為白盒覆蓋。

以上兩者完全可以相輔相成,用代碼覆蓋結果反向的檢查需求覆蓋(用例)的測試是否充分完整。

如果做覆蓋率測試?我們可以借助一些網上流行的各種覆蓋率工具,本章主要介紹JaCoCo這個工具。

1.2 JAVA覆蓋率工具介紹

市場上java主要代碼覆蓋率工具:EMMA、JaCoCo

總結一下個人對JaCoCo優勢的理解:

(1)JaCoCo支持分支覆蓋、引入了Agent模式。

(2)EMMA官網已經不維護了,JaCoCo是其團隊開發的,可以理解為一個升級版。

(3)JaCoCo社區比較活躍,官網也在不斷的維護更新。

我們前期使用的EMMA,也做了全量、差異覆蓋率,和精準耦合也結合在了一起,但後來考慮到JaCoCo的優勢,也就全部切換了過來。

1.2.1 JaCoCo簡述

JaCoCo是一個開源的覆蓋率工具(官網地址: http://www.eclemma.org/JaCoCo/ ),它針對的開發語言是java,其使用方法很靈活,可以嵌入到Ant、Maven中;可以作為Eclipse插件,可以使用其JavaAgent技術監控Java程序等等。

很多第三方的工具提供了對JaCoCo的集成,如sonar、Jenkins等。

JaCoCo包含了多種尺度的覆蓋率計數器,包含指令級覆蓋(Instructions,C0coverage),分支(Branches,C1coverage)、圈復雜度(CyclomaticComplexity)、行覆蓋(Lines)、方法覆蓋(non-abstract methods)、類覆蓋(classes),後面會一一介紹。

我們先看看其覆蓋率結果展現如下圖1-1所示,方便讀者先有一個大概的了解。

圖1-1  覆蓋率報告結果部分截圖

標示綠色的為行覆蓋充分,標紅色的為未覆蓋的行,黃色菱形的為分支部分覆蓋,綠色菱形為分支完全覆蓋。

通過這個報告的結果就可以知道代碼真實的執行情況,便於我們分析評估結果。

1.2.2 JaCoCo基本概念

行覆蓋率:度量被測程序的每行代碼是否被執行,判斷標準行中是否至少有一個指令被執行。

類覆蓋率:度量計算class類文件是否被執行。

分支覆蓋率:度量if和switch語句的分支覆蓋情況,計算一個方法裏面的總分支數,確定執行和不執行的 分支數量。

方法覆蓋率:度量被測程序的方法執行情況,是否執行取決於方法中是否有至少一個指令被執行。

指令覆蓋:計數單元是單個java二進制代碼指令,指令覆蓋率提供了代碼是否被執行的信息,度量完全 獨立源碼格式。

圈復雜度:在(線性)組合中,計算在一個方法裏面所有可能路徑的最小數目,缺失的復雜度同樣表示測 試案例沒有完全覆蓋到這個模塊。

1.2.3 JaCoCo 原理

1.註入方式介紹

這個圖包含了幾種不同的收集覆蓋率信息的方法,每種方法的實現方法都不一樣,帶顏色的部分是JaCoCo比較有特色的地方。

上面各個名次含義(帶顏色的為JaCoCo支持):

上表JaCoCo支持的部分,再詳細的解釋下:

(1)JaCoCo在Byte Code時使用的ASM技術修改字節碼方法,可以修改Jar文件、class文件字節碼文件。

(2)JaCoCo同時支持on-the-fly和offline的兩種插樁模式。

On-the-fly插樁:

JVM中通過-javaagent參數指定特定的jar文件啟動Instrumentation的代理程序,代理程序在通過Class Loader裝載一個class前判斷是否轉換修改class文件,將統計代碼插入class,測試覆蓋率分析可以在JVM執行測試代碼的過程中完成。

Offline模式:

在測試前先對文件進行插樁,然後生成插過樁的class或jar包,測試插過樁 的class和jar包後,會生成動態覆蓋信息到文件,最後統一對覆蓋信息進行處理,並生成報告。

On-the-fly和offline比較:

On-the-fly模式更方便簡單進行代碼覆蓋分析,無需提前進行字節碼插樁,無需考慮classpath 的設置。

存在如下情況不適合on-the-fly,需要采用offline提前對字節碼插樁:

(1)運行環境不支持java agent。

(2)部署環境不允許設置JVM參數。

(3)字節碼需要被轉換成其他的虛擬機如Android Dalvik VM。

(4)動態修改字節碼過程中和其他agent沖突。

(5)無法自定義用戶加載類。

2.JaCoCo執行最小的java版本

最小需要Java1.5

3.字節碼處理方式

JaCoCo通過註入來修改和生成java字節碼,使用的是ASM庫。

4.java方法控制流分析

JaCoCo是如何在字節碼註入的?

我們帶著疑問來看下面的內容:

先舉個實例,有個java方法:

編譯後轉換成字節碼後,內容如下:

我們知道JaCoCo是字節碼註入方式,它是通過一個Probe探針的方式來註入的,具體如下:

探針是字節指令集插入到java方法中,程序執行後可以被記錄,它不會改變原有代碼的行為。

我們看看探針前後插入比較:

顏色的部分就是探針註入的地方。

JaCoCo是根據控制流Type來采用不同的探針插入策略的。

一個用java字節碼定義的java方法的控制流圖可能有以下的type,每一個type連接一個源指令與目標指令,type不同探針的註入策略也會不同,如下是type定義:

探針不改變該方法的行為,但記錄他們已被執行的事實,從理論上講,可以在控制流圖的每一個邊插入一個探針,作為探針實現本身需要多個字節碼指令,這將增加幾倍的類文件的大小和執行速度。

事實上,只需要一個幾個探頭,根據每個方法的控制流的方法,下面說明了如何在不同的邊緣類型的情況下添加額外的指令:

一個instrumented class可以用以下代碼檢索其探針數組實例:

JaCoCo是用一個布爾數組來實現探針,每個探針對應於該數組中的項。當以下四個字節碼指令觸發時探針進行輸入設置為true:

JaCoCo對行探針是這樣處理的,添加兩行指令之間的一個額外的探針時,後續行至少包含一個方法調用。

以上是JaCoCo插樁原理,如果想深入了解,可以去看看它的源碼實現。

1.3 JaCoCo使用方式

使用方式有很多,這裏貼出了相應的參考鏈接,根據項目的不同可以靈活供有需要的讀者去學習。

1.3.1 Apache Ant方式

參見 http://eclemma.org/jacoco/trunk/doc/ant.html

主要有以下幾種,具體使用就不介紹了,應用寶是用的這種方式,後續有介紹。

Task coverage、Task agent、Task dump、Task merge、Task report、Task instrument

1.3.2 命令行方式

參見 http://www.eclemma.org/jacoco/trunk/doc/agent.html

使用方式說明:

主要放在JAVA_OPTS中,比如:

由AgentOptions的getVMArgument方法加載,各參數入AgentOptions的對應參數,為後續操作做為輸入。

下面是官網的所有參數說明:

系統在jvm停止的時候會dump覆蓋率信息。

關鍵的核心代碼在這裏,Agent.java在有一段代碼

Runtime.getRuntime().addShutdownHook這個方法的意思就是在jvm中增加一個關閉的鉤子,當jvm關閉的時候,會執行系統中已經設置的所有通過方法addShutdownHook添加的鉤子,當系統執行完這些鉤子後,jvm才會關閉。所以這些鉤子可以在jvm關閉的時候進行內存清理、對象銷毀等操作。

也就是在JVM關閉的時候調用agent.shutdown(),也就是寫覆蓋率數據。

1.3.3 Apache Maven方式

參見 http://www.eclemma.org/jacoco/trunk/doc/maven.html

這種方式適合Maven的項目。

下面簡單說下調用方式原理:

就拿官方的Offline Example來說吧,其內容如下:

註意藍色的部分,上面的配置主要做了以下幾個事情:

(1)項目已jar包方式打包,引入junit和jacoco。

(2)Build時執行instrument、report、check。

(3)覆蓋率生成到target/jacoco.exec

我們看看他是怎麽觸發調用的。

在jacoco源碼中:jacoco-maven-plugin\target\classes\META-INF\maven\org.jacoco\jacoco-maven-plugin目錄下有個plugin-help.xml文件,它裏面標明了具體的調用方式。

截出instrument這段,關鍵地方就是下面藍色部分。

官網上關於參數的說明:

給出一個整理後的表格:

再給一個jacoco的maven部分的代碼目錄:

到這裏,大家應該清楚其調用的方式了吧。

1.3.4 Eclipse EclDmma Plugin方式

具體步驟如下:

(1)在Eclipse菜單中選擇Help → Install New software…

(2)在安裝彈框中輸入http://update.eclemma.org/,勾選出現的版本。

(3)核對版本,點擊Next。

(4)根據向導完成安裝。

(5)使用就不說了。

1.3.5 與Jekins集成

(1)先要在jenkins上安裝JaCoCo的插件,安裝完成之後在job的配置項中可以增加這個選項(如圖1-2):

圖1-2

(2)選擇後出現(圖1-3):

圖1-3

第一個錄入框是你的覆蓋率文件(exec),第二個是class文件目錄,第三個是源代碼文件目錄。

(3)配置好了之後進行構建,構建完成之後job首頁就會出現覆蓋率的趨勢圖(圖1-4),鼠標點擊趨勢圖可以看到覆蓋率詳情(圖1-5) ,包括具體覆蓋率數據和源碼的覆蓋率情況:

圖1-4  趨勢圖

圖1-5  覆蓋率詳情

未完待續:

JaCoCo原理篇就介紹到這裏了,後續還有項目實踐篇和踩坑篇,實踐篇主要介紹下JaCoCo在實際業務中的使用情況,踩坑篇裏面包含了幾個當時遇到的比較棘手的問題的解決思路,有興趣的童鞋請關註。

本章完~

 

來自:http://tmq.qq.com/2016/08/java-code-coverage-tools-jacoco-principle/

 


Tags: 測試結果 覆蓋率 JAVA 產品 軟件

文章來源:


ads
ads

相關文章
ads

相關文章

ad