jacoco(spring boot启动) agent tcpserver使用方案

公司突然要求自动化测试对代码的覆盖率,故研究了一波jacoco相关

现状

  1. 要拉取的是接口自动化测试的覆盖率,非单元测试的,所以本身必须是在服务部署通过的情况下进行覆盖率的收集
  2. 我们这使用的是容器,java springboot的框架

agent官网去学习了一波

调研了一波

  • ant和maven的方法都是在编译过程中单元测试时出分辨率
  • jacoco agent是在服务启动后,收集代码覆盖率

https://www.jacoco.org/jacoco/trunk/doc/

本次主要会用到2个功能 agent和cli

https://www.jacoco.org/jacoco/trunk/doc/agent.html

https://www.jacoco.org/jacoco/trunk/doc/cli.html

其实实际使用并不难,主要是在springboot的启动命令里面加入javaagent的参数配置,官方提供了2种方案(tcpclient没看到外面有人使用 故先忽略)

  1. output=file
    • 在每次服务结束时统一收集覆盖率dump
    • java -javaagent:/tmp/jacoco/lib/jacocoagent.jar=includes=*,output=file,append=true,destfile=/tmp/jacoco/service/demo/jacoco.exec -jar demo-0.0.1-SNAPSHOT.jar 
  2. output=tcpserver
    • 开放一个tcp端口,可以在过程中收集覆盖率dump
    • java -javaagent:/tmp/jacoco/lib/jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=localhost,append=true -jar demo-0.0.1-SNAPSHOT.jar 
    • 需要通过jacococli.jar 来获取dump
    • java -jar jacococli.jar dump --address localhost --port 6300 --destfile ./jacoco-demo.exec
      • 语句解释:出自https://testerhome.com/topics/20632
        1. -javaagent
          jdk5之后新增的参数,主要用来在运行jar包的时候,以一种方式介入字节码加载过程,如有兴趣自行百度。注意后面有个冒号:

        2. /home/admin/jacoco/jacocoagent.jar
          需要用来介入class文件加载过程的jar包,想深入了解的,百度“插桩”哈。
          这是一个jar包的绝对路径。

        3. includes=*
          这个代表了,启动时需要进行字节码插桩的包过滤,*代表所有的class文件加载都需要进行插桩。
          假如你们公司内部代码都有相同的包前缀:com.mycompany
          你可以写成:

          includes=com.mycompany.*
        4. output=tcpserver
          这个地方不用改动,代表以tcpserver方式启动应用并进行插桩

        5. port=2014
          这是jacoco开启的tcpserver的端口,请注意这个端口不能被占用

        6. address=192.168.110.1
          这是对外开发的tcpserver的访问地址。可以配置127.0.0.1,也可以配置为实际访问ip
          配置为127.0.0.1的时候,dump数据只能在这台服务器上进行dump,就不能通过远程方式dump数据。
          配置为实际的ip地址的时候,就可以在任意一台机器上(前提是ip要通,不通都白瞎),通过ant xml或者api方式dump数据。
          举个栗子:
          我如上配置了192.168.110.1:2014作为jacoco的tcpserver启动服务,
          那我可以在任意一台机器上进行数据的dump,比如在我本机windows上用api或者xml方式调用dump。
          如果我配置了127.0.0.1:2014作为启动服务器,那么我只能在这台测试机上进行dump,其他的机器都无法连接到这个tcpserver进行dump。

获取出来的就是exec的dump文件,那么接下来就要生成报告了

官方又提供了2种方案,其他我

  1. ant转报告
  2. 开发工具直接展示
  3. jacococli.jar 转报告

ant本身需要安装环境,还要定制build.xml,个人比较懒,而且平时使用ant的机会也不多,所以没用这个方案

开发工具直接看结果可以(idea Analyze->Show Coverage Data->选择exec文件),但后续不利于做二次开发

jacococli.jar 本身有report方法是专门用来转报告的  

java -jar jacococli.jar report ./jacoco-demo.exec --classfiles /Users/oukotoshuu/IdeaProjects/demo/target/classes/com  --sourcefiles /Users/oukotoshuu/IdeaProjects/demo/src/main/java --html report --xml report.xml

经个人尝试:

  --classfiles 必须项,是编译后target 文件夹下的classes里面的com

Jacoco 包含了多种尺度的覆盖率计数器,包含指令级(Instructions,C0 coverage),分支(Branches,C1 coverage)、圈复杂度(Cyclomatic Complexity)、行(Lines)、方法(Non-abstract Methods)、类(Classes)。

➢ Instructions:Jacoco 计算的最小单位就是字节码指令。指令覆盖率表明了在所有的指令中,

哪些被指令过以及哪些没有被执行。这项指数完全独立于源码格式并且在任何情况下有效,不需要类文件

的调试信息。

➢ Branches:Jacoco 对所有的 if 和 switch 指令计算了分支覆盖率。这项指标会统计所有的分支数

量,并同时支出哪些分支被执行,哪些分支没有被执行。这项指标也在任何情况都有效。异常处理不考虑在分支范围内。

➢ Cyclomatic Complexity:Jacoco 为每个非抽象方法计算圈复杂度,并也会计算每个类,包,组的复杂度。根据 McCabe1996 的定义,圈复杂度可以理解为覆盖所有的可能情况最少使用的测试用

例数。这项参数也在任何情况下有效。

➢ Lines:该项指数在有调试信息的情况下计算。

➢ Methods:每一个非抽象方法都至少有一条指令。若一个方法至少被执行了一条指令,就认为它被执行过。因为 JaCoco 直接对字节码进行操作,所以有些方法没有在源码显示(比如某些构造方法和由编

译器自动生成的方法)也会被计入在内。

➢ Classes:每个类中只要有一个方法被执行,这个类就被认定为被执行。同 5 一样,有些没有在源码声明的方法被执行,也认定该类被执行。

  --sourcefiles 理论可以不传,不传的话 只能到文件级的展示,再细 需要具体代码和行数就需要这个了

        --csv  这个维度只能到代码文件级 pass

        --xml  这个就比较细致了适合目前的需求

接下来目标就是再实际过程中实施了,到时候看下坑有多大吧,后面根据这个为基础搞实时的代码覆盖率,长路漫漫 学习不止~

参考:

https://www.jianshu.com/p/464a140b2c67 

https://testerhome.com/topics/20632

原文地址:https://www.cnblogs.com/edwar172038/p/11491267.html