简介

Jacoco是一个开源的覆盖率工具。Jacoco可以嵌入到Ant 、Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序。很多第三方的工具提供了对Jacoco的集成,如sonar、Jenkins等。

官网地址:http://www.eclemma.org/jacoco/

Jacoco包含了多种尺度的覆盖率计数器,包含指令级(Instructions,C0coverage),分支(Branches,C1coverage)、圈复杂度(CyclomaticComplexity)、行(Lines)、方法(non-abstract methods)、类(classes)。

²  行覆盖率:度量被测程序的每行代码是否被执行,判断标准行中是否至少有一个指令被执行。

²  类覆盖率:度量计算class类文件是否被执行。

²  分支覆盖率:度量if和switch语句的分支覆盖情况,计算一个方法里面的总分支数,确定执行和不执行的分支数量。

²  方法覆盖率:度量被测程序的方法执行情况,是否执行取决于方法中是否有至少一个指令被执行。

²  指令覆盖:计数单元是单个java二进制代码指令,指令覆盖率提供了代码是否被执行的信息,度量完全 独立源码格式。

²  圈复杂度:在(线性)组合中,计算在一个方法里面所有可能路径的最小数目,缺失的复杂度同样表示测 试案例没有完全覆盖到这个模块。

目前支持的启动类型:

²  Local Java application java程序(有main)

²  Eclipse/RCP application 桌面应用程序

²  Equinox OSGi framework

²  JUnit test 单元测试

²  TestNG test

²  JUnit plug-in test

²  JUnit RAP test

²  SWTBot test

²  Scala application

覆盖率工具工作流程

1. 对Java字节码进行插桩,On-The-Fly和Offine两种方式。 
2. 执行测试用例,收集程序执行轨迹信息,将其dump到内存。 
3. 数据处理器结合程序执行轨迹信息和代码结构信息分析生成代码覆盖率报告。 
4. 将代码覆盖率报告图形化展示出来,如html、xml等文件格式。

插桩原理

主流代码覆盖率工具都采用字节码插桩模式,通过钩子的方式来记录代码执行轨迹信息。其中字节码插桩又分为两种模式On-The-Fly和Offine。On-The-Fly模式优点在于无需修改源代码,可以在系统不停机的情况下,实时收集代码覆盖率信息。Offine模式优点在于系统启动不需要额外开启代理,但是只能在系统停机的情况下才能获取代码覆盖率。

On-The-Fly插桩 Java Agent

1、JVM中通过-javaagent参数指定特定的jar文件启动Instrumentation的代理程序
2、代理程序在每装载一个class文件前判断是否已经转换修改了该文件,如果没有则需要将探针插入class文件中。
3、代码覆盖率就可以在JVM执行代码的时候实时获取。
4、典型代表:Jacoco

On-The-Fly插桩 Class Loader

1、自定义classloader实现自己的类装载策略,在类加载之前将探针插入class文件中

2、典型代表:Emma

Offine插桩

1、在测试之前先对文件进行插桩,生成插过桩的class文件或者jar包,执行插过桩的class文件或者jar包之后,会生成覆盖率信息到文件,最后统一对覆盖率信息进行处理,并生成报告。
2、Offline插桩又分为两种:
       1》Replace:修改字节码生成新的class文件
       2》Inject:在原有字节码文件上进行修改
3、典型代表:Cobertura

On-The-Fly和Offine比较

1、On-The-Fly模式更加方便的获取代码覆盖率,无需提前进行字节码插桩,可以实时获取代码覆盖率信息
2、Offline模式适用于以下场景:
          运行环境不支持java agent
          部署环境不允许设置JVM参数
          字节码需要被转换成其他虚拟机字节码,如Android Dalvik VM
          动态修改字节码过程中和其他agent冲突
          无法自定义用户加载类

JaCoCo作用

监测应用程序在测试时有多少源码被执行。

测试包括:单元测试、功能测试、接口测试
执行包括:指令、分支、圈复杂度、行、方法、类

代码覆盖率的意义

Martin Fowler(重构那本书的作者)曾经写过一篇博客来讨论这个问题,他指出:把测试覆盖作为质量目标没有任何意义,而我们应该把它作为一种发现未被测试覆盖的代码的手段。

1、分析未覆盖部分的代码,从而反推在前期测试设计是否充分,没有覆盖到的代码是否是测试设计的盲点,为什么没有考虑到?需求/设计不够清晰,测试设计的理解有误,工程方法应用后的造成的策略性放弃等等,之后进行补充测试用例设计。

2、检测出程序中的废代码,可以逆向反推在代码设计中思维混乱点,提醒设计/开发人员理清代码逻辑关系,提升代码质量。
3、代码覆盖率高不能说明代码质量高,但是反过来看,代码覆盖率低,代码质量不会高到哪里去,可以作为测试自我审视的重要工具之一。

影响

1、进行完全的覆盖性测试,提升设计能力; ---》对于测试
2、检验是否存在冗余代码,理清逻辑思路; ---》对于开发

准备工作

下载jacoco,进入jacoco官网:http://www.eclemma.org/jacoco/

保证当前JDK在1.5以上

获取到jacoco包jacoco-0.8.2.zip:

Windows下直接解压,得到   D:\JAR\jacoco-0.8.2   目录自定义即可

目录结构图如下:

Jacoco的lib目录结构如下:

其中jacocoagent.jar是放置在Tomcat配置中作为代理同时启动的jar包

对于jacocoant.jar是利用ant对覆盖率进行处理的jar包

着重介绍和使用jacococli.jar,此包可直接在客户端上执行,无需其他软件。

Tomcat配置

1 关闭Tomcat, window是shutdown.bat扩展名、Linux是shutdown.sh扩展名

2 修改Windows下catalina.bat,在第二行添加如下脚本:

set JAVA_OPTS=-javaagent:D:\JAR\jacoco-0.8.2\lib\jacocoagent.jar=includes=*,output=tcpserver,port=9527,address=127.0.0.1,append=true -Xverify:none

   Linux修改catalina.sh,在第二行添加如下脚本:

JAVA_OPTS="-javaagent:/home/systemtools/jacoco-0.8.2/lib/jacocoagent.jar=includes=*,output=tcpserver,port=9527,address=192.168.43.100,append=true -Xverify:none"

JAVA_OPTS="-javaagent:[yourPath/]jacocoagent.jar=includes=com.companyName.*,output=tcpserver,port=PORT,address=IP -Xverify:none"
参数说明:
1. yourPath 是放 jacocoagent.jar 文件的目录路径;那么 `jacocoagent.jar` 这个 `jar` 包的路径就是在准备工作里下载下来的 `zip` 包,解压之后的 `lib` 目录下。
2. includes 是指要收集哪些类(注意不要光写包名,最后要写.*),不写的话默认是*,会收集应用服务上所有的类,包括服务器和其他中间件的类,一般要过滤(当然如果你愿意写*也完全没有问题,如:`includes=com.*` or `includes=*`);
3. output 有 4 个值,分别是 file、tcpserver、tcpclient、mbean,默认是 file。使用 file 的方式只有在停掉应用服务的时候才能产生覆盖率文件,而使用 tcpserver 的方式可以在不停止应用服务的情况下下载覆盖率文件,后面会介绍如何使用 dump 方法来得到覆盖率文件。
4. address 是 IP 地址,IP 就是 Tomcat 服务器的机器的 IP,至于是写 `服务器本机的 IP` 还是写 `127.0.0.1` 要看情况 1) 如果是在 Tomcat 服务器上执行 `ant dump` 的话,就直接写 `address=127.0.0.1` 2) 如果执行 `ant dump` 不是在 Tomcat 服务器上执行的,就得写服务器本机的IP(切记)
5. port 是端口(端口比较随便,找个能用的端口就行,直接我为什么将端口写成 `8044`,我的想法是 `BUG 死死` 与 `8044` 挺配的,所以就用它作为端口号了) (`address` 和 `port` 是使用 tcpserver 方式需要的 2 个参数,也是执行 ant dump 方法必须要用到的。)
6. `-Xverify:none`:这个参数是防止启动主程序异常才加的(非强制,可以不加)

3 启动Tomcat,Windows下使用startup.bat,Linux下使用startup.sh

4 验证JAVA_OPTS是否有修改正确

Windows下在cmd窗口使用WMIC命令,回车

回显:wmic:root\cli>

在>后面输入:process where name="java.exe"  命令

查看回显信息

注意:可能信息很长,而且在一行,需要拖动下方的滚动条查看

Linux下载终端窗口中输入ps -ef | grep tomcat

jacocoagent.jar的使用参数:

使用jacococli.jar包

使用释疑

查看帮助,命令为:java -jar jacococli.jar --help

对于具体的command查看帮助信息。

命令如下:

java -jar jacococli.jar dump –help       # 获取服务器端tcpserver模式输出文件jacoco.exec

具体参数信息:

java -jar jacococli.jar instrument --help   # 离线java class文件和jar文件的指令集

java -jar jacococli.jar merge --help    #合并多个生成的.exec文件为一个新文件

java -jar jacococli.jar report --help     #通过读取.exec和java的class文件生成不同文件格式的报告

java -jar jacococli.jar classinfo --help     # 在指定位置打印有关Java类文件的信息

java -jar jacococli.jar execinfo --help    # 以高可读性打印exec文件信息

实例展示

以上面配置的Linux下Tomcat为例,使用命令:

java -jar jacococli.jar dump --address 192.168.43.100 --port 9527 --destfile ./jacoco.exec

引入Jenkins

配置

由于Jenkins提供了jacoco的插件,我们可以通过Jenkins来解析jacoco的exec文件

安装jacoco插件,路径:Jenkins > 系统管理 > 插件管理,在过滤框中输入jacoco进行搜索

选中后,点击【直接安装】按钮

安装成功后可以在插件管理的已安装标签页查看:

回到Jenkins首页,点击【新建任务】创建一个自由风格的job,名称为:TestJacoco

在<配置>中,使用git获取GitHub上的代码================》图略了。。。。。

在构建中,【增加构建步骤】,选择<执行Windows批处理命令>(若Jenkins机器搭建在Linux下,可以选择<执行shell>)

点击左下角的【保存】按钮。

执行<立即构建>

此时可以手动将jacococli.jar包放置到TestJacoco的工作目录下。

目录例如:

C:\Users\username\.jenkins\workspace\TestJacoco

将编译好的.class 文件的文件夹,放置在jacococli.jar包的同一个目录下。

此时,在<配置>中【增加构建后操作】选择:<Record JaCoCo coverage report>

点击【保存】

然后执行<立即构建>

可以在工程的目录下查看到如图所示信息:

点击图中区域任意位置,可以跳转到如下:

可以通过图中信息,查看所有代码的覆盖率信息。

针对其他的命令的使用,在这里不做逐一的解释。有兴趣可以按照参数列表进行探究。

针对Springboot - 多module - 代码覆盖率统计

说明:web为启动模块,依赖关系:web->service->manager->dao->entity+common

新建了test模块,当前模块里什么代码都没有,但是POM中显式依赖了其他所有模块,显式依赖就是为了聚合其他所有模块的统计报告;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>     <groupId>com.mx.server.tsp</groupId>
    <artifactId>pom-management-test</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>pom-management-test</name>     <parent>
        <groupId>com.mx.server.tsp</groupId>
        <artifactId>pom-management</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>     <dependencies>
        <!-- 依赖所有子模块  -->
        <dependency>
            <groupId>com.mx.server.tsp</groupId>
            <artifactId>pom-management-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mx.server.tsp</groupId>
            <artifactId>pom-management-service</artifactId>
        </dependency>         <dependency>
            <groupId>com.mx.server.tsp</groupId>
            <artifactId>pom-management-manager</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mx.server.tsp</groupId>
            <artifactId>pom-management-dao</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mx.server.tsp</groupId>
            <artifactId>pom-management-entity</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mx.server.tsp</groupId>
            <artifactId>pom-management-common</artifactId>
        </dependency>
    </dependencies>
    
</project>

  

注:test模块是为了统一代码覆盖率报告而单独建的模块,且test->web+service+manager+dao+entity+common(test依赖其他所有子模块)

综上,为了合并多module的代码测试覆盖率统计报告,

(1)采用了JaCoCo插件,

(2)且单独为了聚合统计报告而新建了一个test模块,当前模块没有任何代码,只是显式依赖了其他所有子模块,

(3)在项目根目录下执行mvn install后,即可通过test模块下的target/site/jacoco-aggregate/index.html查考到合并后的代码测试覆盖率报告;

针对具体的jacoco插件,进行数据分析。执行mvn test获取结果。

            

    <!-- 单元覆盖率插件-->
           <plugin>
              <groupId>org.jacoco</groupId>
              <artifactId>jacoco-maven-plugin</artifactId>
              <version>0.7.9</version>
              <executions>
                  <execution>
                  <id>pre-unit-test</id>
                  <goals>
                      <goal>prepare-agent</goal>
                  </goals>
                  <configuration>
                      <propertyName>jacocoArgLine</propertyName>
                  </configuration>
                  </execution>
                  <execution>
                  <id>post-unit-test</id>
                  <phase>package</phase>
                  <goals>
                      <goal>report</goal>
                  </goals>
                  </execution>
              </executions>
            </plugin>

<!---按照需要选择插件数据---->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<outputDirectory>target/jacoco-out</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!------->
        <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <argLine>-Xmx256M ${jacocoArgLine}</argLine>
                    <skip>false</skip>
                    <testFailureIgnore>false</testFailureIgnore>
                    <includes></includes>
                    <excludes>
                        <!-- 由于测试controller类需要启动auth应用进行登录请求,故剔除 -->
                        <exclude>**/controller/*ControllerTest.java</exclude>
                    </excludes>
                </configuration>
            </plugin>

  

=======================END=========================

JaCoCo在Tomcat服务器上监控代码覆盖率的使用方法的更多相关文章

  1. 详细的图文教程来实现 eclipse环境下如何配置tomcat,并且把项目部署到Tomcat服务器上

    很多初学,尤其自学JavaWeb的朋友首次在eclipse下配置tomcat时,总会有种难下手的感觉,在此,通过图文解说的方法,最直观的向大家演示一遍该配置过程. 第一部分:eclipse环境下如何配 ...

  2. Java Project部署到Tomcat服务器上

    所有的JAVA程序员,在编写WEB程序时,一般都通过工具如 MyEclipse,编写一个WEB Project,通过工具让这个WEB程序和Tomcat关联.其实在我们可以通过JAVA程序部署到Tomc ...

  3. linux的tomcat服务器上部署项目的方法

    在tomcat服务器上部署项目的前提,是我们已经准备好了tomcat服务器.在CentOs环境下部署JavaWeb环境,部署tomcat服务器在前面的文章中已经总结过了,可以参考以前文章. 一  to ...

  4. Linux服务器上监控网络带宽的18个常用命令 zz

    Linux服务器上监控网络带宽的18个常用命令 本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量 ...

  5. 一个tomcat服务器上部署多个Web项目,不同域名访问

    [参考]一个tomcat服务器上部署多个项目,不同域名访问 我们一个服务器只按装了一个tomcat服务器,现在有多个项目或者多个域名访问,下面来进行配置 在这里我们只需要修改conf下的server. ...

  6. Springboot解决war包放到Tomcat服务器上404的特殊情况

    Springboot解决war包放到Tomcat服务器上404的特殊情况 原文链接:https://www.cnblogs.com/blog5277/p/9330577.html 原文作者:博客园-- ...

  7. Linux服务器上监控网络带宽的18个常用命令和工具

    一.如何查看CentOS的网络带宽出口 检查维护系统的时候,经常会要查看服务器的网络端口是多大的,所以需要用到Linux的一个命令. 如何查看CentOS的网络带宽出口多大?可以用下面的命令来查看. ...

  8. Linux服务器上监控网络带宽的18个常用命令nload, iftop,iptraf-ng, nethogs, vnstat. nagios,运用Ntop监控网络流量

    Linux服务器上监控网络带宽的18个常用命令 本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量 ...

  9. IDEA上传图片到tomcat服务器上

    前端页面: JS代码: //选中图片 var form = document.getElementById("danxuan"); // 用表单来初始化 var formData ...

随机推荐

  1. [Z] C#程序中设置全局代理(Global Proxy)

    https://www.cnblogs.com/Javi/p/7274268.html 1. HttpWebRequest类的Proxy属性,只要设置了该属性就能够使用代理了,如下: 1        ...

  2. 24小时学通Linux内核之调度和内核同步

    心情大好,昨晚我们实验室老大和我们聊了好久,作为已经在实验室待了快两年的大三工科男来说,老师让我们不要成为那种技术狗,代码工,说多了都是泪啊,,不过我们的激情依旧不变,老师帮我们组好了队伍,着手参加明 ...

  3. DeBug Python代码全靠print函数?换用这个一天2K+Star的工具吧,改进版

    pysnooper是代码debug神器,比无限low print好很多和也比日志debug好一些,比断点调试也好一些,这个很犀利的装饰器. https://www.toutiao.com/a66829 ...

  4. JS精准倒计时(支持自定义模板)

    /** * 倒计时 Create By TuJia @2017.10.17 * 使用方法: * leftTimer.run(container[,theme][,callback]); * * 支持 ...

  5. 使用glusterfs 作为 kubernetes PersistentVolume PersistentVolumeClaim 持久化仓库,高可用Rabbitmq,高可用mysql,高可用redis

    glusterfs 怎么集群,网上一搜铺天盖地的 可利用这个特点做单节点高可用,因为K8S 哪怕节点宕机了 master 会在随意一台节点把挂掉的复活 当然我是在自己的环境下跑,经过网络的gluste ...

  6. C# WinForm窗体隐藏右上角最小化、最大化、关闭按钮

    C# WinForm窗体隐藏右上角最小化.最大化.关闭按钮 如何赢藏WinForm窗体的右上角按钮  设置设置ControlBox = false: 设置ControlBox = false:

  7. VS Code设置成中文界面

    1.打开VS Code,按:ctrl+shift+p打开指令面板,输入lang,选择Configure Display Language 2.将"locale"后面的"e ...

  8. OJ#1002 又是a+b

    题目描述: 给定两个正整数a.b(0 < a,b < =10000),求出a+b的和 输入描述: 多组输入,每组输入为一行,里面有2个数a,b(0 < a,b < =10000 ...

  9. vue2.0 --- vuex (一)

    之前做vue项目中没有使用vuex  一直使用vue-router 组件.路由一直的转换,烦不胜烦 今天研究一下vuex vuex是什么: vuex是专门为vue.js应用程序开发的状态管理模式. 解 ...

  10. HTML02单词

    form:表单action:行动(提交的路径)method:方法(提交的方式)input:输入type:类型text:文本(文本输入项)password:密码radio:单选按钮checkbox:复选 ...