Skip to content

代码覆盖率统计 Jacoco 技术

一、代码覆盖率统计的作用

1.1 面试题:你如何保障测试工作的质量?

常规方式:

  • 根据需求文档里面写的功能需求,设计测试用例
  • 用例评审 - 确保测试用例尽量覆盖到了这些功能

问题:

  • 管理角度问题 - 测试人员是否执行了这些用例?
  • 开发偷偷改动了代码

需要一个 客观的凭据(考核/数据)保障功能是不是测试到位?

解决方案思路来源:

  • 功能都是由代码实现的,触发之后,代码运行实现了这个效果。
  • 如果能够监控到测试过程中哪些代码被运行了,哪些代码没运行

1.2 什么是测试代码的覆盖率?

为什么它能够代表质量的客观数据:

  • 系统功能是由开发人员编写代码实现
  • 测试用例执行模拟用户去使用系统,触发代码的执行

代码覆盖率:统计哪些代码被执行了

举例: 开发写了100行代码,测试人员执行的系统测试之后,统计代码覆盖率:80%

意义: 100行代码,80行代码被触发执行了,20行代码没被执行。可能出现的原因:

  1. 开发人员代码有很多没用垃圾代码(提高了软件系统的维护难度,低质量的表现)
  2. 测试人员对于功能的使用没有覆盖到位(没触发对应的功能代表用例不到位)

二、Jacoco 框架工具介绍

JAVA本身没有代码覆盖率统计功能,难点:如何去统计这个代码有没有被执行呢?

2.1 Jacoco 框架是什么

Jacoco 是面向 Java 的开源代码覆盖率工具,Jacoco 以 java 代理模式运行,它负责在运行测试时检测字节码。Jacoco 会深入研究每个指令,并显示每个测试过程中要执行的行,为了收集覆盖率数据,Jacoco 使用ASM 即时进行代码检测,并在此过程中从 JVM Tool Interface 接收事件,最终生成代码覆盖率报告。

Jacoco 的运行模型有两种:

  1. 离线(offline):编译时插桩,在测试前先对文件进行插桩,然后生成插过桩的 class 或 jar 包,测试插过桩的 class 和 jar 包后,会生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。
  2. 在线(on the fly):在线模式就是在应用启动时加入 jacoco agent 进行插桩,在开发、测试人员使用应用期间实时地进行代码覆盖率分析。

2.2 Jacoco 安装教程

  • 准备JDK,在本机输入:java --version 确定是否显示对应的版本
  • 下载 Jacoco,官网:https://www.jacoco.org/jacoco/ 【本教程使用的 0.8.8 版本进行演示】
  • 下载解压之后就可以进行使用

三、Jacoco 代码覆盖率项目实战应用

3.1 Jacoco 的使用场景

场景1:偏白盒测试 - 支持单元测试代码覆盖率统计

  • 开发自测
  • 白盒测试
  • 开发人员编写单元测试代码

场景2:偏黑盒测试 - 代码覆盖率统计

  • 针对于测试人员
  • 手工测试或者自动化测试,执行完毕,可以通过工具看到代码覆盖率

覆盖率颜色说明:绿色-执行过;红色-未执行;黄色-分支部分执行

3.2 项目实操演练

前提条件:

  1. 了解一些代码的概念,能够看懂一些代码更好。
  2. Java项目为例,你自己有一个可运行的 JAVA项目
  3. 借助 Jacoco 去分析代码覆盖率

第一步:启动应用

正常情况下,通过目前最主流 springboot 应用程序启动方式:java -jar 项目.jar 进行启动。

注意: 这个方法不可行,JAVA本身没有提供代码统计的功能。所以我们需要在启动java程序的时候,添加jvm的配置参数,给当前程序额外增加代码统计功能。

第二步:添加 jvm 配置参数

bash
# 添加jacoco统计能力(jacoco解压之后 lib文件夹里面 jacocoagent.jar)
java -javaagent:/temp/jacocoagent.jar=includes=com.java2nb.*,output=tcpserver,port=6300,address=192.168.1.42,append=true -jar 项目.jar

参数指定如下:

  • Java Agent:启动时加载Java Agent以实现字节码修改、监控等功能
  • javaagent:jacocoagent.jar路径,在jacoco的lib目录,比如:\jacoco-0.8.8\lib
  • includes:你要统计的java代码包有哪些(项目代码 + 第三方库/模块)
  • output:代码覆盖率统计的结果数据以什么形式导出(tcpserver)
  • port、address:访问什么IP端口,去获取统计数据

示例命令:

bash
java -javaagent:./jacoco-0.8.8/lib/jacocoagent.jar=includes=com.java2nb.*,output=tcpserver,port=6300,address=192.168.1.4,append=true -jar api-project.jar

第三步:分析执行数据

根据埋点的数据,进行覆盖率分析

场景: A 测试人员针对注册功能设计了如下用例:

  1. 输入正确的手机号,及密码,及验证码,测试是否注册成功

  2. 输入重复的手机号,及密码,及验证码,测试是否提示重复注册

  3. 执行用例之后,0 BUG,测试通过

  4. 通过 jacoco 代码覆盖分析测试用例及用例执行是否覆盖到位

bash
# 特定的jacoco客户端去获取项目中的代码执行数据
java -jar /temp/jacococli.jar dump --address IP地址 --port 端口号 --destfile ./jacoco_tcp_01.exec

参考示例:

bash
java -jar ./jacoco-0.8.8/lib/jacococli.jar dump --address 192.168.1.4 --port 6300 --destfile ./jacoco_tcp_01.exec
  1. 把数据变成一个 html 可视化报告
bash
java -jar /temp/jacococli.jar report ./jacoco_tcp_01.exec --sourcefiles D:\work\course\test\project\项\src\main\java --classfiles D:\work\course\test\project\项\target\classes --html ./report_test --encoding utf-8

覆盖率报告结合源码进行展现,需要项目源码。

没测试到位的情况:根据覆盖率统计,反向分析到某些代码分支没测到,增加用例。

问题:代码被执行过,就代表测试用例完善?

  • 否定。如果代码没被触发,覆盖率很低,一定代表系统测试有些功能没测试到。
  • 如果代码覆盖率很高,不代表测试用例完善。

总结

QA 质量体系:所有的测试技术都是为了提高质量的下限。测试的目的不是为了发现所有BUG。

Powered by VitePress

🔒 需要口令解锁

关注微信公众号 测开阿Duang
回复关键词 「密码」 获取口令

公众号二维码

解锁后本浏览器长期有效