Java单元测试用例与覆盖率
相关准备
项目测试准备
SpringBoot项目:
- SpringBoot项目地址:https://github.com/jinglv/spring-boot-restful-api.git
- SpringBoot项目,编写项目相关单元测试用例
SonarQube平台
详见:SonarQube平台介绍 一篇,介绍SonarQube平台如何搭建
Java测试报告与覆盖率
官网各语言分析:https://docs.sonarqube.org/latest/analysis/coverage/
Property | Scope | Example | Description |
---|---|---|---|
sonar.junit.reportPaths | Project-wide | target/surefire-reports,myModule/target/surefire-reports | Import tests execution reports(Surefire XML format). Set the property with a list of comma-separated paths to the directories containing the XML reports. |
sonar.jacoco.reportPaths | Project-wide | target/jacoco.exec,target/jacoco-it.exec(default) | Import JaCOCO code coverage reports. Set the property to the path of the JaCOCO.exec reports,merge multiple reports. (if you are using a version of SonarQube prior to 6.2 please use sonar.jacoco.reportPath proerty) |
Java单元测试用Sonar执行
获取结果
进入项目工程下,进行单元测试
1
jingdeMacBook-Pro:spring-boot-restful-api apple$ mvn clean test
将测试结果上传到SonarQube平台
1
2
3
4
5
6
7jingdeMacBook-Pro:spring-boot-restful-api apple$ mvn sonar:sonar \
-Dsonar.host.url=http://60.205.228.49:9000/ \
-Dsonar.login=053ed1077e82a2bb36eebf619d24d75b8c5738b9 \
-Dsonar.ws.timeout=300 \
-Dmaven.test.skip=false \
-Dsonar.junit.reportPaths='./target/surefire-reports'-Dsonar.junit.reportPaths
:上传执行的测试报告
查看执行结果
SonarQube平台上,查看结果
分析结果
Sonar的官方文档中对各项指标有详细的描述,具体讲解可见官方文档。
查看Measures(度量)界面
等级A、B、C、D、E,从不同的维度进行等级打分,则看图很清楚的看到代码质量的好坏
通用测试数据导入
官方文档介绍:https://docs.sonarqube.org/latest/analysis/generic-test/
通⽤测试数据Generic Test Data
- 通⽤覆盖率数据: sonar.coverageReportPaths
- 通⽤测试执⾏数据: sonar.testExecutionReportPaths
sonar.testExecutionReportPaths
1 | <testExecutions version="1"> |
sonar.coverageReportPaths
1 | <coverage version="1"> |
通用测试的用途
- 合并覆盖率,转换为通用覆盖率数据
- 把其他工具的覆盖率转化过来
- 把git diff的代码映射多来
演示
本地创建一个目录
1
jingdeMacBook-Pro:JavaProject apple$ mkdir testdata
将
sonar.testExecutionReportPaths
中的示例,复制到一个xml文件中1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16jingdeMacBook-Pro:JavaProject apple$ vim generic_test.xml
jingdeMacBook-Pro:JavaProject apple$ cat generic_test.xml
<testExecutions version="1">
<file path="testx/ClassOneTest.xoo">
<testCase name="test1" duration="5"/>
<testCase name="test2" duration="500">
<skipped message="short message">other</skipped>
</testCase>
<testCase name="test3" duration="100">
<failure message="short">stacktrace</failure>
</testCase>
<testCase name="test4" duration="500">
<error message="short">stacktrace</error>
</testCase>
</file>
</testExecutions>注意:里面的file要对应的已有的文件路径
使用sonar-scanner工具,扫描传到SonarQube服务上
1
jingdeMacBook-Pro:JavaProject apple$ sonar-scanner -Dsonar.testExecutionReportPaths=testdata/generic_test.xml -Dsonar.projectKey=generic-test -Dsonar.projectName=generic-test -Dsonar.sources=./spring-boot-restful-api/ -Dsonar.java.binaries=./spring-boot-restful-api/target/
这种方式就适合多语言的测试用例上传
覆盖率统计
覆盖率统计的⼯具
- emma
- cobertura
- jacoco
目前最流行的覆盖率统计工具是jacoco,具体详情介绍请看JaCOCO介绍
Jacoco的底层技术
字节码插桩
- ASM:所有字节码插桩框架的底层,性能最高,apm框架的核心基础
- JavaAssist:简单易用
- ByteBuddy、 BTrace、 JVM-Sandbox。。。
覆盖率统计原理
- 对JVM的字节码插桩
- 基于block插桩
- 计算覆盖的代码块
jacoco使用
jacoco官方文档:https://www.jacoco.org/jacoco/trunk/doc/index.html
根据官方文档说明,执行命令,获取帮助文档:mvn help:describe -Dplugin=org.jacoco:jacoco-maven-plugin -Ddetail
1 | # 进入工程目录下执行 |
命令行执行,jacoco分析及获得测试报告
1 | jingdeMacBook-Pro:spring-boot-restful-api apple$ mvn clean org.jacoco:jacoco-maven-plugin:0.8.5:prepare-agent test org.jacoco:jacoco-maven-plugin:0.8.5:report -Dmaven.test.failure.ignore=true -Dmaven.test.skip=false |
也可基于Maven项目的pom.xml文件中添加
进入到项目目录下,target/site/jacoco目录下,打开index.html文件查看测试覆盖率报告
之后,我们将测试覆盖率报告上传到SonarQube平台,通过SonarQube进行测试结果的分析
1 | jingdeMacBook-Pro:spring-boot-restful-api apple$ mvn sonar:sonar -Dsonar.host.url=http://xx.xxx.xxx.xx:9000/ -Dsonar.login=053ed1077e82a2bb36eebf619d24d75b8c5738b9 -Dsonar.ws.timeout=300 |
查看前面的SonarQube平台,我们看到覆盖率的值为0.00%,我们己经将jacoco的覆盖率报告已上传,这是查看SonarQube平台的结果
也可以使用sonar-scanner进行测试报告的上传SonarQube
1 | SONARQUBE_HOST=http://xxx.xxx.xxx.xxx:9000 |