Jacoco收集單元測試、集成測試和系統功能測試覆蓋率
2020-02-27
1 安裝版本
2 被測系統代碼示例
3 收集單元測試覆蓋率
4 收集集成和功能測試覆蓋率
代碼覆蓋率可在單元測試、系統測試和系統功能測試中使用
- 單元測試:測試左移,在代碼提交前,可制定覆蓋率要求,若不滿足,不能提交
- 集成測試:接口測試
- 系統功能測試:通過用戶界面操作
1 安裝版本
- jacoco-0.8.2.zip 解壓到:D:\software\jacoco
- apache-ant-1.10.6-bin.zip 解壓到:D:\software\ant
2 被測系統代碼示例
源代碼:jacocodemo.zip
該示例示基於springboot框架的后端系統,主要是兩個數字的加減乘除,提供restful接口給外部調用
圖1 被測系統jacocoDemo
3 收集單元測試覆蓋率
配置被測項目pom.xml,添加插件設置:

<!--maven測試為 default 生命周期中的test階段。--> <!--test階段與 maven-surefire-plugin 的test目標相綁定了, 這是一個內置的綁定。--> <!--Maven通過插件來執行 JUnit 和 TestNG 的測試用例。--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> </plugin> <!--執行單元測試命令:mvn test--> <!--結果在target目錄下生產jacoco-unit.exec文件,表明jacoco正確執行--> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.3</version> <configuration> <!--指定生成 .exec 文件的存放位置--> <destFile>target/coverage/jacoco-unit.exec</destFile> <!--Jacoco 是根據 .exec 文件生成最終的報告,所以需指定 .exec 的存放路徑--> <dataFile>target/coverage/jacoco-unit.exec</dataFile> </configuration> <executions> <execution> <id>jacoco-initialize</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>jacoco-site</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin>
執行maven命令
mvn test
命令執行日志如下:

D:\Code\jacocodemo>mvn test [INFO] Scanning for projects... [INFO] [INFO] -----------------------< com.example:jacocodemo >----------------------- [INFO] Building jacocodemo 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- jacoco-maven-plugin:0.8.3:prepare-agent (jacoco-initialize) @ jacocodemo --- [INFO] argLine set to -javaagent:D:\\software\\maven\\repo\\m2\\org\\jacoco\\org.jacoco.agent\\0.8.3\\org.jacoco.agent-0.8.3-runtime.jar=destfile=D:\\Code\\jacocodemo\\target\\coverage\\jacoco-unit.exec [INFO] [INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ jacocodemo --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ jacocodemo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 6 source files to D:\Code\jacocodemo\target\classes [INFO] /D:/Code/jacocodemo/src/main/java/com/example/controller/MathController.java: D:\Code\jacocodemo\src\main\java\com\example\controller\MathController.java使用了未經檢查或不安全的操作。 [INFO] /D:/Code/jacocodemo/src/main/java/com/example/controller/MathController.java: 有關詳細信息, 請使用 -Xlint:unchecked 重新編譯。 [INFO] [INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ jacocodemo --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\Code\jacocodemo\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ jacocodemo --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to D:\Code\jacocodemo\target\test-classes [INFO] [INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ jacocodemo --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.example.service.MathServiceTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 s - in com.example.service.MathServiceTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- jacoco-maven-plugin:0.8.3:report (jacoco-site) @ jacocodemo --- [INFO] Loading execution data file D:\Code\jacocodemo\target\coverage\jacoco-unit.exec [INFO] Analyzed bundle 'jacocodemo' with 6 classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5.227 s [INFO] Finished at: 2020-02-27T16:07:58+08:00 [INFO] ------------------------------------------------------------------------
生成exec文件和report文件如下圖2所示
圖2 單元測試單面覆蓋率文件
由於類MathService方法add被調用,jacoco收集到此信息,如下圖3所示
圖3 覆蓋率詳情
4 收集集成和功能測試覆蓋率
1 把被測被測系統打包並改名成 jacocodemo.jar
mvn package
2 啟動被測系統,並通過javaagentJavaAgent會監聽服務器端設置的TCP port,然后把收集到的信息(jacoco.exec)寫入TCP connection
java -javaagent:D:/software/jacoco/lib/jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=10.8.116.81,append=true -jar D:/Code/jacocodemo/target/jacocodemo.jar
3 配置ant的build.xml文件,並把它放到被測系統代碼根目錄
build.xml

<?xml version="1.0" encoding="UTF-8"?> <project name="JacocoDmo" xmlns:jacoco="antlib:org.jacoco.ant" default="jacoco"> <!--Jacoco 的安裝路徑--> <property name="jacocoantPath" value="D:\software\jacoco\lib\jacocoant.jar"/> <!--最終生成 .exec 文件的路徑,Jacoco 就是根據這個文件生成最終的報告的--> <property name="jacocoexecPath" value="D:\Code\jacocodemo\target\coverage\jacoco-integation.exec"/> <!--生成覆蓋率報告的路徑--> <property name="reportfolderPath" value="D:\Code\jacocodemo\target\coverage\jacoco-report"/> <!--遠程 Tomcat 服務的 ip 地址--> <property name="server_ip" value="10.8.116.81"/> <!--前面配置的遠程 Tomcat 服務打開的端口,要跟上面配置的一樣--> <property name="server_port" value="6300"/> <!--源代碼路徑--> <property name="checkOrderSrcPath" value="D:\Code\jacocodemo\src\main\java" /> <!--.class 文件路徑--> <property name="checkOrderClasspath" value="D:\Code\jacocodemo\target\classes" /> <!--讓 ant 知道去哪兒找 Jacoco--> <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"> <classpath path="${jacocoantPath}" /> </taskdef> <!--dump 任務: 根據前面配置的 ip 地址,和端口號, 訪問目標 Tomcat 服務,並生成 .exec 文件。--> <target name="dump"> <jacoco:dump address="${server_ip}" reset="false" destfile="${jacocoexecPath}" port="${server_port}" append="true"/> </target> <!--jacoco 任務: 根據前面配置的源代碼路徑和 .class 文件路徑, 根據 dump 后,生成的 .exec 文件,生成最終的 html 覆蓋率報告。--> <target name="report"> <delete dir="${reportfolderPath}" /> <mkdir dir="${reportfolderPath}" /> <jacoco:report> <executiondata> <file file="${jacocoexecPath}" /> </executiondata> <structure name="JaCoCo Report"> <group name="Check Order related"> <classfiles> <fileset dir="${checkOrderClasspath}"> <!-- 過濾不必要的文件 --> <exclude name="**/R.class"/> <exclude name="**/R$*.class"/> <exclude name="**/*$ViewInjector*.*"/> <exclude name="**/BuildConfig.*"/> <exclude name="**/Manifest*.*"/> </fileset> </classfiles> <sourcefiles encoding="UTF-8"> <fileset dir="${checkOrderSrcPath}" /> </sourcefiles> </group> </structure> <html destdir="${reportfolderPath}" encoding="UTF-8" /> <csv destfile="${reportfolderPath}/coverage-report.csv" encoding="UTF-8"/> <xml destfile="${reportfolderPath}/coverage-report.xml" encoding="UTF-8"/> </jacoco:report> </target> </project>
4 用postman調用被測系統接口,如下圖4所示
圖4 postman調用被測系統接口
5 執行ant dump拉取jacoco.exec覆蓋率信息,執行ant report生成覆蓋率報告
D:\Code\jacocodemo>ant dump Buildfile: D:\Code\jacocodemo\build.xml dump: [jacoco:dump] Connecting to /10.8.116.81:6300 [jacoco:dump] Dumping execution data to D:\Code\jacocodemo\target\coverage\jacoco-integation.exec BUILD SUCCESSFUL Total time: 0 seconds D:\Code\jacocodemo>ant report Buildfile: D:\Code\jacocodemo\build.xml report: [mkdir] Created dir: D:\Code\jacocodemo\target\coverage\jacoco-report [jacoco:report] Loading execution data file D:\Code\jacocodemo\target\coverage\jacoco-integation.exec [jacoco:report] Writing bundle 'Check Order related' with 6 classes BUILD SUCCESSFUL Total time: 0 seconds
從覆蓋率報告可以看到subtract方法被覆蓋,如圖5所示
圖5 接口測試覆蓋方法subtract
參考:
[1] Jacoco遠程統計tomcat服務(Windows系統)的代碼覆蓋率