基于jacoco实现代码覆盖率统计

基于jacoco实现代码覆盖率统计

Administrator 19 2024-08-02

一、代码覆盖率是什么?

  代码覆盖率,是指通过计算测试过程中被执行的源代码占全部代码的比例,进而间接度量软件质量的过程。它在保证测试质量的时候潜在保证实际产品的质量。可以基于此在程序中寻找到没有被测试用例测试过的地方,进一步创建新的测试用用例来增加覆盖率。按性质,它属于白盒测试的范畴,即主要依据源代码的内部结构来设计测试用例,通过设计不同的输入来测试软件的不同部分。

  代码覆盖率统计是服务于研发的单元测试,确保代码的行覆盖率来保障所有语句的可执行性,而这同样也可以服务于测试,作为接口测试工作的衡量标准,通过统计结果映射出接口测试场景的覆盖度,接口测试用例考虑的越齐全代码覆盖率结果自然越高。

  规范完善的用例设计方案可以保障 85%+ 的代码覆盖率,反过来说只要被测服务测试执行结果达到 85%+ ,那接口测试的结果也具备可靠性。如果低于85%,可配合开发定位未覆盖到的内容,明确问题。如果是代码冗余导致的问题可提交缺陷给研发进行代码优化,如果是业务场景未覆盖到,应补齐测试用例并执行,测试结束后还得完善用例的设计方法。

二、代码覆盖率统计工具都有什么?

  不同开发语言有不同的代码覆盖率统计工具,常见的工具:

  • java: jacoco
  • go: go test coverage
  • python: coverage

  基于我们目前服务端所选语言,这里我们只讲jacoco
   Jacoco是面向Java的开源代码覆盖率工具,Jacoco以java代理模式运行,它负责在运行测试时检测字节码。Jacoco会深入研究每个指令,并显示每个测试过程中要执行的行,为了收集覆盖率数据,Jacoco使用ASM即时进行代码检测,并在此过程中从JVM Tool Interface 接收事件,最终生成代码覆盖率报告。
   Jacoco 的运行模型有两种:
   1. 离线(offline)
   编译时插桩,在测试前先对文件进行插桩,然后生成插过桩的class或jar包,测试插过桩 的class和jar包后,会生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。
   2. 在线(on the fly)
   在线模式就是在应用启动时加入jacoco agent进行插桩,在开发、测试人员使用应用期间实时地进行代码覆盖率分析
   针对测试人员来说,我更倾向于使用第二种方法,在线插桩
   下面聊聊具体方法

三、jacoco的安装部署

image.png

  • 上传至服务器并解压
mkdir jacoco
cd jacoco
rz
unzip jacoco-0.8.11.zip

  lib目录下的jacocoagent.jar和jacococli.jar就是我们要使用的工具

image.png

  • 明确被测对象

  如果被测对象只是单服务,服务运行包即是要统计的对象;如果被测对象是集成环境,包含多服务,那就需要拆解成多个统计任务。
   如测评小程序,服务启动方式是通过启动jar包来执行,applet-cp.jar即是要统计的服务对象。

image.png

  • 执行插桩命令
nohup java -javaagent:jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=localhost,append=true -jar applet-cp.jar
# coagent.jar   jacocoagent.jar包的路径
# applet-cp.jar     项目的jar包
# output=tcpserver     代表以 tcpserver 方式启动应用并进行插桩
# port=6300  Jacoco    开启的 tcpserver 的端口
# address=localhost    对外开发的 tcpserver 的访问地址,可以配置 127.0.0.1,也可以配置为实际访问ip
  • 执行测试用例
    若有自动化测试脚本则执行脚本,也可手动执行测试用例。

  • cli包dump生成exec文件(注意一定要测试完毕之后)

java -jar /data/jacoco/lib/jacococli.jar dump --address localhost --port 6300 --destfile /data/apps/applet-cp/jacoco-cp.exec
  • cli包exec生成html报表
java -jar jacococli.jar reportjacoco-cp.exec --classfiles /data/apps/applet-cp/applet-cp_class/BOOT-INF/classes/com --sourcefiles /data/apps/applet-cp/applet-cp_src/src/main/java --html /data/apps/applet-cp/html-report --xml report.xml --encoding=utf-8

# jacoco-cp.exec    要解析的exec文件的路径
# --classfiles      需要指定生成的classes文件目录
# --sourcefiles     需要指定源码的文件目录,非必传参数,若有的话,可在报告中详细到源码覆盖展示
  • 生成报告后将整个html-report目录下载到本地

  打开index.html
image.png

  • 结果分析
     Total展示即为总的覆盖率统计,统计维度为行覆盖

image.png

四、应用场景

在测试结束后,根据代码覆盖率分析测试覆盖到的场景,若是覆盖率足够多,则相对来说覆盖完整,若覆盖率较低,则需分析某些场景是否没有覆盖到,或者开发代码有冗余。

在测试过程中,可以发现其实有些代码并非只是实现功能逻辑,老话说得好,一行代码实现功能,一百行代码用来防刁民,指的其实就是针对一些异常场景或者防止用户走接口来实现正常操作无法实现的操作,在测评小程序中,前端层面在提交题目时已经做了校验,若有题目未答题,提交按钮置灰无法点击,若后端未做处理,这时候我们通过调用接口,将某个题目传空值,此时若提交成功,无疑便产生了一条脏数据。

未测之前此语句分支背景色为红色,表示未覆盖:
image.png

覆盖后背景色转变为绿色,表示已覆盖:

image.png