Java 程式碼覆蓋率調研報告

麦兜珊發表於2020-04-08

jacoco 官網:https://jenkins.io/
jekins 官網:https://www.eclemma.org/jacoco/trunk/doc/

一、Demo 應用簡介

1、涉及技術:

Springboot+maven+mybatis+mysql

2、提供的介面:


二、單元測試程式碼覆蓋

1、jacoco 實現原理:

Offline 模式:
在測試前先對檔案進行插樁,然後生成插過樁的 class 或 jar 包,測試插過樁的 class 和 jar 包後,會生成動態覆蓋資訊到檔案,最後統一對覆蓋資訊進行處理,並生成報告。

2、jacoco 執行方式:

針對 maven 專案,在 pom.xml 中新增依賴包,在編譯時執行單元測試用例,最終的報告生成到 target 目錄中

3、專案 pom.xml 配置:

<build>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <!--jacoco-->
 <plugin>
         <groupId>org.jacoco</groupId>
         <artifactId>jacoco-maven-plugin</artifactId>
         <version>0.8.2</version>
         <!--這裡的execution ,每一個執行的goal,對應的id必須是唯一的-->
 <executions>
            <execution>
               <id>prepare-agent</id>
               <goals>
                  <goal>prepare-agent</goal>
               </goals>
            </execution>
            <execution>
               <id>report</id>
               <phase>prepare-package</phase>
               <goals>
                  <goal>report</goal>
               </goals>
            </execution>
            <execution>
               <id>post-unit-test</id>
               <phase>test</phase>
               <goals>
                  <goal>report</goal>
               </goals>
               <configuration>
                  <dataFile>target/jacoco.exec</dataFile>
                  <outputDirectory>target/jacoco-ut</outputDirectory>
               </configuration>
            </execution>
         </executions>
         <configuration>
            <systemPropertyVariables>
               <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
            </systemPropertyVariables>
         </configuration>
      </plugin>
   </plugins>
</build>

4、手動執行 jacoco 程式碼覆蓋率報告:



5、與 Jekins jacoco plugin 外掛整合:

job 名稱:cssjacoco





三、實時程式碼覆蓋率

1、jacoco 實現原理:

On-the-fly 插樁:
JVM 中透過-javaagent 引數指定特定的 jar 檔案啟動 Instrumentation 的代理程式,代理程式在透過 ClassLoader 裝載一個 class 前判斷是否轉換修改 class 檔案,將統計程式碼插入 class,測試覆蓋率分析可以在 JVM 執行測試程式碼的過程中完成。

2、jacoco 執行方式:

jar 包方式啟動:
java -javaagent:C:\Work\css\jacoco-0.8.2\lib\jacocoagent.jar=includes=,output=tcpserver,port=8086,address= -jar css-0.0.1-SNAPSHOT.jar

映象方式啟動:
構建 docker 映象:
在當前目錄中新建 Dockerfile 檔案,執行 docker build -t dockername:v1 .命令

執行完畢後檢視是否映象建立成功:docker images:

啟動映象:docker run -d -it -p 8089:8089 f2e3d36e34c4
http://221.122.129.111:8089/CRUD/ListUser

查詢容器日誌:docker logs -f 容器 id
查詢啟動的 docker 程序:docker ps -l
刪除 docker 容器:docker rm 容器 id
刪除 docker 映象:docker rmi 映象 id
匯出容器:docker export 容器 id > 檔名.tar
進入 docker 內部:docker exec 4d70138f6755 /bin/sh
LInux 查詢埠使用情況:netstat -anp|grep 8089

3、使用 ant 構建生成覆蓋率報告:

jacocoant.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project name="JaCoCo" default="run" xmlns:jacoco="antlib:org.jacoco.ant">
    <!--Jacoco的安裝路徑-->
 <property name="jacocoAntPath" value="C:\Work\css\jacoco-0.8.2\lib/jacocoant.jar"/>
    <!--生成.exec檔案的路徑,Jacoco就是根據這個檔案生成HTML報告的-->
 <property name="jacocoExecPath" value="C:\Work\css\jacocoresult\jacoco.exec"/>
    <!--生成覆蓋率報告的路徑-->
 <property name="jacocoReportPath" value="C:\Work\css\jacocoresult\jacocoReport"/>
    <!--遠端服務的ip地址 -->
 <property name="server_ip" value="39.105.66.41"/>
    <!--前面javaagent配置的遠端服務開啟的埠,要跟上面配置的一樣-->
 <property name="server_port_css" value="8086"/>
    <!--css專案原始碼路徑-->
 <property name="css_sourceaPath" value="C:\Work\css\css\src\main\java\"/>
    <!--css專案class檔案路徑-->
 <property name="css_classPath" value="C:\Work\css\css\target\classes\"/>
    <!--讓ant知道去哪兒找Jacoco-->
 <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
        <classpath path="${jacocoAntPath}"/>
    </taskdef>
    <target name="run">
        <echo message="start..."/>
        <echo message="dump..."/>
        <antcall target="dump"/>
        <echo message="report..."/>
        <antcall target="report"/>
        <echo message="end..."/>
    </target>
    <!--dump任務:
 根據前面配置的ip地址,和埠號,訪問目標服務,並生成.exec檔案。
 reset=true時,會在dump出exec檔案後,清空覆蓋率資料;
 append=false時,dump出的exec檔案會覆蓋原有的exec檔案;append=true時,dump出的exec檔案
 追加至原有的exec檔案;
 -->
 <target name="dump">
        <jacoco:dump address="${server_ip}" reset="false" destfile="${jacocoExecPath}/class_css.exec" port="${server_port_css}" append="true"/>
    </target>
    <!--jacoco任務:
 根據前面配置的原始碼路徑和.class檔案路徑,
 dump後生成的.exec檔案,生成最終的html覆蓋率報告。-->
 <target name="report">
        <jacoco:report>
            <executiondata>
                <file file = "C:\Work\css\jacocoresult\jacoco.exec\class_css.exec" />
            </executiondata>
            <structure name="JaCoCo Report">
                <!--group name 對應生成的報告中的列表名-->
 <group name="css_Demo">
                    <sourcefiles encoding="UTF-8">
                        <fileset dir="${css_sourceaPath}"/>
                    </sourcefiles>
                    <classfiles>
                        <fileset dir="${css_classPath}"/>
                    </classfiles>
                </group>
            </structure>
            <html destdir="${jacocoReportPath}" encoding="utf-8"/>
            <csv destfile="${jacocoReportPath}/report.csv"/>
            <xml destfile="${jacocoReportPath}/report.xml"/>
        </jacoco:report>
    </target>
</project>

執行 ant -f jacocoant.xml 生成程式碼覆蓋率報告:

###4、與 Jekins jacoco plugin 外掛整合:

環境配置:

Job 名稱:jacoco_report





###5、不同使用場景下的設定
ant dump 任務屬性:




相關文章