基於 Jenkins + JaCoCo 實現功能測試代碼覆蓋率統計

首發於 Jenkins 中文社區html

使用 JaCoCo 統計功能測試代碼覆蓋率?

對於 JaCoCo,有所瞭解但又不是很熟悉。 "有所瞭解"指的是在 CI 實踐中已經使用 JaCoCo 對單元測試代碼覆蓋率統計: 當代碼 push 到代碼倉庫後,用 JaCoCo 進行單元測試代碼覆蓋率統計,並將相應數據推送到 SonarQube。 "不是很熟"指的是應用場景也僅限於此,並未進行過多研究與實踐。java

前不久,有測試同事提出,想要在實際測試時,用 JaCoCo 統計功能測試代碼覆蓋率。 其主要目的是在通過功能測試後,經過查看代碼覆蓋率統計的相關指標,加強對軟件質量的信心。 經查閱資料,證實這是可行的。git

因爲對 JaCoCo 不甚瞭解,因而查閱官網資料對 JaCoCo 進一步瞭解。github

進一步瞭解 JaCoCo

JaCoCo,即 Java Code Coverage,是一款開源的 Java 代碼覆蓋率統計工具。 它由 EclEmma 團隊根據多年來使用和集成現有庫的經驗教訓而建立。web

JaCoCo 願景

JaCoCo 應該爲基於 Java VM 的環境中的代碼覆蓋率分析提供標準技術。 重點是提供一個輕量級的、靈活的、文檔良好的庫,以便與各類構建和開發工具集成。bash

JaCoCo 產品功能

  • 指令(C0)、分支(C1)、行、方法、類型和圈複雜度的覆蓋率分析。
  • 基於 Java 字節碼,所以也能夠在沒有源文件的狀況下工做。
  • 經過基於 Java agent 的實時檢測進行簡單集成。其餘集成場景(如自定義類加載器)也能夠經過 API 實現。
  • 框架無關性:平穩地與基於 Java VM 的應用程序集成,好比普通 Java 程序、OSGi 框架、web 容器或 EJB 服務器。
  • 兼容全部已發佈的 Java 類文件版本。
  • 支持不一樣的 JVM 語言。
  • 支持幾種報告格式( HTML、XML、CSV )。
  • 遠程協議和 JMX 控件,以便在任什麼時候間點從覆蓋率 agent 請求執行數據 dump 。
  • Ant 任務,用於收集和管理執行數據並建立結構化覆蓋報告。
  • Maven 插件,用於收集覆蓋信息並在Maven構建中建立報告。

非功能特性

  • 使用簡單和與現有構建腳本和工具集成。
  • 良好的性能和最小的運行時開銷,特別是對大型項目。
  • 輕量級實現,對外部庫和系統資源的依賴性最小。
  • 全面的文檔。
  • 完整文檔化的 API ( JavaDoc ) 和用於與其餘工具集成的示例。
  • 迴歸測試基於 JUnit 測試用例,具備完整的功能測試覆蓋率。

對 JaCoCo 能夠與現有構建腳本和工具進行集成這裏作進一步說明: 官方提供了 Java API、Java Agent 、CLI、Ant 、Maven、Eclipse 這幾種集成方式; 第三方提供了諸如與 Gradle、IDEA、Jenkins 等其它工具的集成方式。服務器

拋開理論,開始實踐

JaCoCo 不只支持統計本地服務的代碼覆蓋率,也支持統計遠程服務的代碼覆蓋率。 單元測試覆蓋率統計就是統計本地服務的代碼覆蓋率,代碼和運行的服務在一臺機器上,筆者這裏經過使用 JaCoCo Maven 插件完成的。 而功能測試代碼覆蓋率統計則是統計遠程服務的代碼覆蓋率,代碼和運行的服務通常不在一臺機器上,這裏須要藉助 JaCoCo Java agent 實現。app

備註:實際上,JaCoCo Maven 插件也使用了 JaCoCo Java agent,不過用戶不須要直接關係 Java agent 及其選項,Maven 插件都透明地處理了。框架

一、下載 JaCoCo 分發包

能夠從 JaCoCo 官網下載分發包,也能夠從 Maven 倉庫(中央倉庫或私服)下載。 分發包的 lib 目錄下,包括如下庫:maven

二、Java 應用啓動腳本添加 jacocoagent 相關 JVM 參數

須要將 jacocoagent.jar 推送到部署應用的服務器上,筆者這裏用 Ansible 進行了批量推送。 Java 應用啓動腳本須要加入相似下面的 JVM 參數:

JAVA_OPTS="$JAVA_OPTS -javaagent:/path/jacocoagent.jar=includes=*,output=tcpserver,append=false,address=$IP,port=$JACOCO_PORT"
複製代碼

這樣在應用成功啓動後,會暴露一個 TCP 服務,客戶端能夠鏈接到這個服務並獲取執行數據文件。

相關屬性說明以下:

  • append:其中 append=false 表示 dump 每次會生成一個新的執行數據文件,若是 append=true,dump 時則會將數據追加到已存在的執行數據文件。 其中 output=tcpserver 表示 agent 監聽來自被 adrress 和 port 屬性指定的TCP 端口的鏈接,執行數據被寫到這個鏈接;
  • output:若是 output=tcpclient 則表示在啓動時,agent 鏈接到被 adrress 和 port 屬性指定的TCP 端口,執行數據被寫到這個鏈接; 若是 output=file 則表示在 JVM 終止時,執行數據被寫到被 destfile 屬性指定的文件。output 默認值爲 file 。
  • address:當 output 爲 tcpserver 時綁定到的 IP 地址或主機名,或者當 output 爲 tcpclient 時鏈接到的 IP 地址或主機名。 在 tcpserver 模式下,值爲「*」致使代理只接受本機地址上的鏈接。address 默認值爲 127.0.0.1 。
  • port:當 output 方式爲 tcpserver 時綁定到該端口,或者當 output 方式爲 tcpclient 時鏈接到該端口。 在 tcpserver 模式下,端口必須可用,這意味着若是多個 JaCoCo agent 在同一臺機器上運行,則必須指定不一樣的端口。port 默認值爲 6300 。

三、建立及配置 Jenkins Pipeline 任務

Jenkins 任務大體有幾個步驟:拉取代碼,構建,dump 應用執行數據( jacoco.exec ),解析 JaCoCo 產生的 jacoco.exec 文件,而後生成覆蓋率報告(HTML 格式)。 拉取代碼這裏無需多說,配置下從代碼倉庫(SVN/Git)和分支地址就能夠了,比較簡單。 構建這裏用了 Jenkins Pipeline Maven Integration Plugin ,筆者這裏所用的 Maven 命令是 mvn clean package -Dmaven.test.skip=true 。 dump 應用執行數據這裏有多種方式:Ant、CLI、Maven,由於Java 應用是用 Maven 構建的,這裏選擇了 Maven Jacoco Plugin。 解析 JaCoCo 產生的 jacoco.exec 文件,而後生成覆蓋率報告(HTML 格式)筆者這裏使用了 Jenkins Jacoco Plugin。

Jenkins Pipeline 案例以下:

pipeline {
    agent any
    tools {
        jdk 'JDK1.8'
    }
    stages {
        stage('Checkout'){
            steps{
                git branch: '${GIT_BRANCH}', credentialsId: 'xxx-xxx-xx-xx-xxx', url: '${GIT_URL}'
            }
        }
        stage('Build') {
            steps{
                withMaven(maven: 'maven'){
                      sh "mvn clean package -Dmaven.test.skip=true"
                }
            }
        }
        stage('DumpFromServer'){
            steps {
                withMaven(maven: 'maven'){
                      sh 'mvn org.jacoco:jacoco-maven-plugin:0.8.4:dump -Djacoco.address=${SERVER_IP} -Djacoco.port=${JACOCO_PORT}'
                }
            }
        }
        stage('JacocoPublisher') {
            steps {
                 jacoco()
            }
        }
    }
}
複製代碼

JaCoCo 覆蓋率報告,部分截圖以下:

總結

筆者所實現的方式並未覆蓋任何場景,可是大同小異,相關工具的使用詳情能夠查看官網文檔,由於它是最全面的。 筆者但願這個實踐能給有相似訴求的同行一些參考,固然筆者也但願可以和你們互相交流。 同時筆者的 JaCoCo 實踐之路並未結束,可能在使用的過程當中會有一些問題須要解決, 後續也將考慮使用 Jenkins API 爲須要統計功能測試代碼覆蓋率的 Java 應用實例自動生成一個對應的 Jenkins 任務, 並在 Java 應用實例銷燬後,對相應的 Jenkins 任務進行清理等其它功能。

參考

做者:王冬輝

相關文章
相關標籤/搜索