代码覆盖率统计Super-jacoco在公司级容器化项目中的具体应用方案

news2024/11/17 23:54:34

目录

 

一、介绍

二、自己在本地搭建Super-jacoco服务

2.1 准备工作

2.2 部署super jacoco服务

1、下载super jacoco 项目

2、初始化数据库

3、配置application.properties

4、编译super jacoco项目

5、部署 super jacoco 服务

2.3 启动被测项目

2.4、代码覆盖率收集

2.4.1 启动代码覆盖率收集

2.4.2 获取代码覆盖率

三、公司项目级docker容器化项目Super-jacoco应用

3.1 镜像准备

3.2 部署项目

3.3 测试同学部署Super-jacoco服务

3.3.1 、数据库准备,用于存储报告信息等。

3.3.2 配置Super-jacoco服务application.properties信息

 3.3.3、编译super jacoco项目

3.3.4、部署 super jacoco 服务

 3.4、代码覆盖率收集

3.4.1 启动代码覆盖率收集

3.4.2 获取代码覆盖率

四、报错处理

4.1 "errMsg": "统计失败:编译代码出错"

五、Super-jacoco原理

5.1 整体流程

5.2 获取增量代码

5.3. jacoco 二次改造,支持增量方法列表参数

5.4. 执行

5.5. 报告输出

​编辑

5.6、架构

六、相关资料:


一、介绍

Super-jacoco 在jacoco 上发展而来,可以统计增量代码覆盖率的统计。

jacoco 相关说明:jacoco代码覆盖率_jacoco覆盖率_做测试的喵酱的博客-CSDN博客

本文介绍 Super-jacoco 统计手工用例代码覆盖率的统计数据。

主要分两部分:

一、自己在本地搭建Super-jacoco,自己玩一玩

二、在公司的容器化项目中,如何使用Super-jacoco统计手工用例的代码覆盖率

 GitHub项目地址:

GitHub - didi/super-jacoco

GitHub - didi/super-jacoco

尽量使用git命令,直接下载:

git clone https://github.com/didi/super-jacoco.git

二、自己在本地搭建Super-jacoco服务

2.1 准备工作

  1. 准备gitlab用户
  2. 准备一个MySQL数据库5.x或者8.x版本

2.2 部署super jacoco服务

1、下载super jacoco 项目

GitHub - didi/super-jacoco

2、初始化数据库

在super jacoco 项目中,sql/coverage_report.sql 文件用于初始化数据库。

CREATE DATABASE `super-jacoco` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin ;
CREATE TABLE `diff_coverage_report` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `job_record_uuid` varchar(80) NOT NULL COMMENT '请求唯一标识码',
  `request_status` int(10) NOT NULL COMMENT '请求执行状态,1=下载代码成功,2=生成diffmethod成功,3=生成报告成功,-1=执行出错',
  `giturl` varchar(80) NOT NULL COMMENT 'git 地址',
  `now_version` varchar(80) NOT NULL COMMENT '本次提交的commidId',
  `base_version` varchar(80) NOT NULL COMMENT '比较的基准commitId',
  `diffmethod` mediumtext COMMENT '增量代码的diff方法集合',
  `type` int(11) NOT NULL DEFAULT '0' COMMENT '2=增量代码覆盖率,1=全量覆盖率',
  `report_url` varchar(300) NOT NULL DEFAULT '' COMMENT '覆盖率报告url',
  `line_coverage` double(5,2) NOT NULL DEFAULT '-1.00' COMMENT '行覆盖率',
  `branch_coverage` double(5,2) NOT NULL DEFAULT '-1.00' COMMENT '分支覆盖率',
  `err_msg` varchar(1000) NOT NULL DEFAULT '' COMMENT '错误信息',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `sub_module` varchar(255) NOT NULL DEFAULT '' COMMENT '子项目目录名称',
  `from` int(10) NOT NULL DEFAULT '0' COMMENT '1=单元测试,2=环境部署1=单元测试,2=hu',
  `now_local_path` varchar(500) NOT NULL DEFAULT '',
  `base_local_path` varchar(500) NOT NULL DEFAULT '',
  `log_file` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`job_record_uuid`),
  KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='增量代码覆盖率';

CREATE TABLE `diff_deploy_info` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `job_record_uuid` varchar(80) NOT NULL COMMENT '请求唯一标识码',
  `address` varchar(15) NOT NULL COMMENT 'HOST',
  `port` int(10) NOT NULL COMMENT '端口',
  `code_path` varchar(1000) NOT NULL DEFAULT '' COMMENT 'nowVersion代码目录',
  `child_modules` varchar(1000) NOT NULL DEFAULT '' COMMENT '项目子模块名称',
  PRIMARY KEY (`job_record_uuid`),
  KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='服务部署地址';



3、配置application.properties

在下载下来的项目中,application.properties配置信息

src/main/resources/application.properties

# 以下信息需要手动配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/super-jacoco?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#git username & password
gitlab.username=miaojiang
gitlab.password=mj123456

主要配置

数据库的连接信息:url 账号 密码

gitlab 的账号、密码

注意:

数据库的驱动配置,5.x与8.x 版本的MySQL,驱动是不一致的,根据自己的数据库配置。

 如果你的数据库为MySQL 8.x,需要修改项目中的驱动。

1、修改pom.xml文件

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.didichuxing.chefuqa</groupId>
    <artifactId>super-jacoco</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <name>super-jacoco</name>
    <description>project for Spring cloud eureka client</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <entity.target.dir>src/main/java/</entity.target.dir>
        <dao.resources.dir>src/main/resources/</dao.resources.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
        <mysql-connector>8.0.26</mysql-connector>
        <JAVA_HOME>/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home</JAVA_HOME>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jodd</groupId>
            <artifactId>jodd-core</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.core</artifactId>
            <version>0.8.4</version>
        </dependency>
        <dependency>
            <groupId>org.ow2.asm</groupId>
            <artifactId>asm</artifactId>
            <version>7.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis-spring-boot}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
        </dependency>
        <!-- MySQL 连接驱动依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector}</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>15.0</version>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.sharegov</groupId>
            <artifactId>mjson</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.3</version>
        </dependency>
        <!-- pinyin-->
        <dependency>
            <groupId>com.belerweb</groupId>
            <artifactId>pinyin4j</artifactId>
            <version>2.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.jdom</groupId>
            <artifactId>jdom2</artifactId>
            <version>2.0.6</version>
        </dependency>
        <!-- ssh的依赖 -->
        <dependency>
            <groupId>ch.ethz.ganymed</groupId>
            <artifactId>ganymed-ssh2</artifactId>
            <version>build210</version>
        </dependency>
        <dependency>
            <groupId>org.tmatesoft.svnkit</groupId>
            <artifactId>svnkit</artifactId>
            <version>1.8.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.2.3</version>
        </dependency>

        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jgit</groupId>
            <artifactId>org.eclipse.jgit</artifactId>
            <version>4.9.0.201710071750-r</version>
        </dependency>

        <dependency>
            <groupId>com.github.javaparser</groupId>
            <artifactId>javaparser-core</artifactId>
            <version>3.4.4</version>
        </dependency>
        <!-- Swagger2核心包 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <!-- jsoup HTML parser library @ http://jsoup.org/ -->
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>super-jacoco</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar</bootclasspath>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                    <configurationFile>
                        ${basedir}/src/main/resources/tk-mybatis-autogen.xml
                    </configurationFile>
                    <!--允许移动生成的文件 -->
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.26</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>4.1.5</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

2、application.properties修改数据库配置驱动

 下面这个是8.x MySQL的驱动

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


4、编译super jacoco项目

修改完super jacoco项目中的配置文件,就可以编译该项目了。生成super jacoco.jar

5、部署 super jacoco 服务

 启动super-jacoco.jar 服务

执行命令

nohup java -jar super-jacoco.jar &

默认端口为8899

可以8899端口,程序是否启动成功

lsof -i:8899

注意:

在部署 super jacoco 服务的机器上,一定要有以下环境:

1、有mvn环境,如果没有的话,需要配置

2、有git环境,并配置了能拉取被测项目的gitlab账号和密码。

可以自己在这台机器上手动试一下,是否有权限

git clone xxx.xxx.git

相关资料:

Mac下安装Maven&idea配置maven_做测试的喵酱的博客-CSDN博客

mac&linux配置环境变量详解_vim ~/.zshrc-CSDN博客

2.3 启动被测项目

1、在super jacoco项目中,找到jacoco/org.jacoco.agent-0.8.5-runtime.jar 文件。

将org.jacoco.agent-0.8.5-runtime.jar 文件,放在被测服务部署的项目上。

如放置路径为/usr/local/org.jacoco.agent-0.8.5-runtime.jar

被测项目为 mock-server.jar

启动被测项目:

nohup java -javaagent:/usr/local/org.jacoco.agent-0.8.5-runtime.jar=includes=*,output=tcpserver,port=18513,address=*,append=true -jar mock-server.jar > /dev/null 2>&1 &

命令解释:

  • nohup:忽略挂起信号,允许命令在后台运行。

  • java:启动 Java 虚拟机。

  • -javaagent:/usr/local/org.jacoco.agent-0.8.5-runtime.jar=includes=*,output=tcpserver,port=18513,address=*,append=true:配置 JaCoCo 代码覆盖率工具代理,其中:

    • /usr/local/org.jacoco.agent-0.8.5-runtime.jar:指定 JaCoCo 代理 Jar 文件的路径。

    • includes=*:指定要包括在覆盖率报告中的类的匹配模式。此处将所有类都包括在内。

    • output=tcpserver:指定覆盖率信息的输出模式。此处使用 TCP 服务器模式。

    • port=18513:指定 TCP 服务器的端口号。

    • address=*:指定 TCP 服务器的地址。此处使用星号 * 表示接受所有来自任何地址的连接。

    • append=true:指定是否将新的覆盖率数据附加到现有数据文件中。此处附加新的数据以保留历史数据。

  • -jar mock-server.jar:指定要运行的 Jar 文件,即 MockServer 的可执行 Jar 文件。

  • > /dev/null:将标准输出重定向到 /dev/null,即不输出任何信息。

  • 2>&1:将标准错误输出重定向到标准输出。

  • &:将进程置于后台运行。

注意:

port=18513 端口,是在被测试的服务所在服务器上,18513端口上,启一个jacoco监听的服务,一定要保证部署被测项目的机器,放开了18513 端口,且我们有权限访问18513 端口。

启动被测项目后,我们可以查看18513 端口的服务是否启动成功

lsof -i:18513

2.4、代码覆盖率收集

假如:

super jacoco 服务部署在了 123.123.123.123 这台服务上了

被测项目mock-server 部署在了 456.456.456.456 机器上了

2.4.1 启动代码覆盖率收集

1)启动覆盖率收集URL:

http://123.123.123.123 /cov/triggerEnvCov

调用方法:POST参数(body方式传入):

{
	"uuid": "uuid",
	"type": 1,
	"gitUrl": "git@git",
	"subModule": "",
	"baseVersion": "master",
	"nowVersion": "master",
	"address": "456.456.456.456",
	"port": "18513"
}

备注:

IP和port为被测服务所在服务器的IP和端口

uuid: 自定义的一个id,将来拉取覆盖率时,通过这个uuid来拉取

gitUrl: 被测项目的gitlab地址

返回:

{
	"code": 200,
	"data": true,
	"msg": "msg"
}

2.4.2 获取代码覆盖率

覆盖率结果URL:

http://123.123.123.123/cov/getEnvCoverResult

调用方法:

GET

参数:

uuid(String)

返回:

{
	"code": 200,
	"data": {
		"coverStatus": 1,
		"errMsg": "msg",
		"lineCoverage": 100.0,
		"branchCoverage": 100.0,
		"logFile": "file content",
		"reportUrl": "http://"
	},
	"msg": "msg"
}

三、公司项目级docker容器化项目Super-jacoco应用

前提:

需要运维、网络、研发、测试同学的相互配合。

但是整体流程,其实和上面是一致的。

下载Super-jacoco 项目:

git clone https://github.com/didi/super-jacoco.git

然后取出Super-jacoco 项目 中的 jacoco/org.jacoco.agent-0.8.5-runtime.jar 文件,与sql/coverage_report.sql文件。

3.1 镜像准备

本部分公司,主要是由运维同学负责。

举例:

依然是部署mock-server服务。

之前的流程:

运维: 准备 Dockerfile文件---生成镜像

部署被测项目:拉取镜像,拉取被测项目的代码,进行编译,生成jar包。在容器中启动该项目

应用jacoco流程:

运维: 先把jacoco agent 的jar包打 放到某一个公共服务器的位置,
然后编写 Dockerfile文件,在里面写拉jacoco agent  jar包的命令。 最后再通过这个Dockerfile文件生成的image镜像

部署被测项目:

拉取镜像,拉取被测项目的代码,进行编译,生成jar包。在容器中启动该项目。需要配置JAVA_OPTS的环境变量,把java agent信息配置到变量里

 -javaagent:/usr/local/org.jacoco.agent-0.8.5-runtime.jar=includes=*,output=tcpserver,port=18513,address=*,append=true

 服务的启动命令是

java $JAVA_OPTS -jar xxx.jar

这样,就拼接成了完整的运行命令:

java -javaagent:/usr/local/org.jacoco.agent-0.8.5-runtime.jar=includes=*,output=tcpserver,port=18513,address=*,append=true -jar mock-server.jar

运维同学要注意:

要放开18513 这个端口,如果要对该端口做代理的话:

jacoco并非http/https,如果测试环境的k8s集群里面,访问形式为ingress+svc的形式,ingress配置域名,svc配置ClusterIP的模式。但是这个ingress只能代理http/https两种协议的请求。这种代理模式是不通的。需要把svc的ClusterIP改为了NodePort的模式,就可以直接通过公共节点+PORT进行访问了。

3.2 部署项目

负责部署项目的同学 测试/研发,在自己公司的部署平台上,选择上面创建好的镜像,配置部署项目的命令。

3.3 测试同学部署Super-jacoco服务

3.3.1 、数据库准备,用于存储报告信息等。

安装MySQL。

使用sql/coverage_report.sql 初始化MySQL信息

3.3.2 配置Super-jacoco服务application.properties信息

在下载下来的项目中,application.properties配置信息

src/main/resources/application.properties

# 以下信息需要手动配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/super-jacoco?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#git username & password
gitlab.username=miaojiang
gitlab.password=mj123456

主要配置

数据库的连接信息:url 账号 密码

gitlab 的账号、密码

注意:

数据库的驱动配置,5.x与8.x 版本的MySQL,驱动是不一致的,根据自己的数据库配置。

 如果你的数据库为MySQL 8.x,需要修改项目中的驱动,具体修改方式在第二章有写,上面翻一番

 3.3.3、编译super jacoco项目

修改完super jacoco项目中的配置文件,就可以编译该项目了。生成super jacoco.jar

3.3.4、部署 super jacoco 服务

 启动super-jacoco.jar 服务

执行命令

nohup java -jar super-jacoco.jar &

默认端口为8899

可以8899端口,程序是否启动成功

lsof -i:8899

注意:

在部署 super jacoco 服务的机器上,一定要有以下环境:

1、有mvn环境,如果没有的话,需要配置

2、有git环境,并配置了能拉取被测项目的gitlab账号和密码。

可以自己在这台机器上手动试一下,是否有权限

git clone xxx.xxx.git

3、启动super jacoco 服务的机器,一定要有访问被测服务器18513端口的权限。

公司中对服务器权限、端口权限控制的比较严,可能需要走工单进行申请,这个需要注意。

 3.4、代码覆盖率收集

假如:

super jacoco 服务部署在了 123.123.123.123 这台服务上了

被测项目mock-server 部署在了 456.456.456.456 机器上了

3.4.1 启动代码覆盖率收集

1)启动覆盖率收集URL:

http://123.123.123.123 /cov/triggerEnvCov

调用方法:POST参数(body方式传入):

{
	"uuid": "uuid",
	"type": 1,
	"gitUrl": "git@git",
	"subModule": "",
	"baseVersion": "master",
	"nowVersion": "master",
	"address": "456.456.456.456",
	"port": "18513"
}

备注:

IP和port为被测服务所在服务器的IP和端口

uuid: 自定义的一个id,将来拉取覆盖率时,通过这个uuid来拉取

gitUrl: 被测项目的gitlab地址

返回:

{
	"code": 200,
	"data": true,
	"msg": "msg"
}

3.4.2 获取代码覆盖率

覆盖率结果URL:

http://123.123.123.123/cov/getEnvCoverResult

调用方法:

GET

参数:

uuid(String)

返回:

{
	"code": 200,
	"data": {
		"coverStatus": 1,
		"errMsg": "msg",
		"lineCoverage": 100.0,
		"branchCoverage": 100.0,
		"logFile": "file content",
		"reportUrl": "http://"
	},
	"msg": "msg"
}

四、报错处理

4.1 "errMsg": "统计失败:编译代码出错"

背景:

拉取报告时 提示 ,统计失败:编译代码出错

原因:

查看启动super jacoco 服务的日志:

2023-10-12 17:01:14,642 INFO (CodeCloneExecutor.java:45)- uuid miaojiang开始下载代码...
2023-10-12 17:01:16,316 INFO (CodeCloneExecutor.java:52)- uuid miaojiang完成下载代码...
2023-10-12 17:01:16,322 DEBUG (BaseJdbcLogger.java:181)- ==>  Preparing: UPDATE diff_coverage_report SET `request_status`=?, `err_msg`=?, `line_coverage`=?, `branch_coverage`=?, `report_url`=?, `diffmethod`=?, `log_file`=?, `now_local_path`=?, `update_time`=NOW() WHERE job_record_uuid=?
2023-10-12 17:01:16,323 DEBUG (BaseJdbcLogger.java:181)- ==> Parameters: 102(Integer), (String), -1.0(Double), -1.0(Double), (String), (String), http://127.0.0.1:8899/logs/miaojiang.log(String), /Users/zhaohui/app/super_jacoco/clonecode/miaojiang/master(String), miaojiang(String)
2023-10-12 17:01:16,327 DEBUG (BaseJdbcLogger.java:181)- <==    Updates: 1
2023-10-12 17:01:16,328 DEBUG (BaseJdbcLogger.java:181)- ==>  Preparing: UPDATE diff_coverage_report SET `request_status`=?, `err_msg`=?, `line_coverage`=?, `branch_coverage`=?, `report_url`=?, `diffmethod`=?, `log_file`=?, `now_local_path`=?, `update_time`=NOW() WHERE job_record_uuid=?
2023-10-12 17:01:16,329 DEBUG (BaseJdbcLogger.java:181)- ==> Parameters: 3(Integer), (String), -1.0(Double), -1.0(Double), (String), (String), http://127.0.0.1:8899/logs/miaojiang.log(String), /Users/zhaohui/app/super_jacoco/clonecode/miaojiang/master(String), miaojiang(String)
2023-10-12 17:01:16,331 DEBUG (BaseJdbcLogger.java:181)- <==    Updates: 1
IP:127.0.0.1
2023-10-12 17:01:16,335 INFO (CmdExecutor.java:43)- CmdThreadPool:java.util.concurrent.ThreadPoolExecutor@4b5dade5[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
2023-10-12 17:01:16,335 INFO (CmdExecutor.java:48)- executeCmd : bash -c cd /Users/zhaohui/app/super_jacoco/clonecode/miaojiang/master&&mvn clean compile >>/Users/zhaohui/report/logs/miaojiang.log
2023-10-12 17:01:16,346 INFO (CmdExecutor.java:101)- bash: mvn: command not found
2023-10-12 17:01:16,347 INFO (CmdExecutor.java:56)- readLine.stop();
2023-10-12 17:01:16,347 INFO (CmdExecutor.java:58)- progressBar.stop();
2023-10-12 17:01:16,348 INFO (CmdExecutor.java:59)- executeCmd done !!!!!!
2023-10-12 17:01:16,348 INFO (CmdExecutor.java:60)- worker done !!!!!! times = 0s
2023-10-12 17:01:16,349 DEBUG (BaseJdbcLogger.java:181)- ==>  Preparing: UPDATE diff_coverage_report SET `request_status`=?, `err_msg`=?, `line_coverage`=?, `branch_coverage`=?, `report_url`=?, `diffmethod`=?, `log_file`=?, `now_local_path`=?, `update_time`=NOW() WHERE job_record_uuid=?
2023-10-12 17:01:16,350 DEBUG (BaseJdbcLogger.java:181)- ==> Parameters: 203(Integer), 编译代码出错(String), -1.0(Double), -1.0(Double), (String), (String), http://127.0.0.1:8899/logs/miaojiang.log(String), /Users/zhaohui/app/super_jacoco/clonecode/miaojiang/master(String), miaojiang(String)
2023-10-12 17:01:16,352 DEBUG (BaseJdbcLogger.java:181)- <==    Updates: 1
2023-10-12 17:01:16,352 INFO (CodeCovServiceImpl.java:252)- Thread-4计算覆盖率具体步骤...编译失败uuid=miaojiang
2023-10-12 17:01:16,353 INFO (CodeCovServiceImpl.java:309)- Thread-4计算覆盖率具体步骤...编译失败uuid=miaojiang
2023-10-12 17:01:19,981 DEBUG (BaseJdbcLogger.java:181)- ==>  Preparing: SELECT * from diff_coverage_report WHERE `request_status`=? AND `from`=? ORDER BY `update_time` asc limit ?
2023-10-12 17:01:19,987 DEBUG (BaseJdbcLogger.java:181)- ==> Parameters: 0(Integer), 1(Integer), 1(Integer)

根据日志信息,可以看出发生了以下事件:

17:01:14 - miaojiang开始下载代码。
17:01:16 - miaojiang完成下载代码。
17:01:16 - 执行数据库更新操作,更新了diff_coverage_report表的一行数据。
17:01:16 - 执行数据库更新操作,再次更新了diff_coverage_report表的一行数据。
17:01:16 - 从IP地址为127.0.0.1的主机上执行命令:cd /Users/zhaohui/app/super_jacoco/clonecode/miaojiang/master&&mvn clean compile >>/Users/zhaohui/report/logs/miaojiang.log,但是出现了错误:bash: mvn: command not found。
17:01:16 - 终止读取日志和进度条。
17:01:16 - 执行命令结束,执行时间为0秒。
17:01:16 - 再次执行数据库更新操作,更新了diff_coverage_report表的一行数据,将request_status设为203,err_msg设为"编译代码出错"。
17:01:16 - Thread-4处理计算覆盖率的具体步骤时发生编译失败,uuid为miaojiang。
17:01:19 - 执行数据库查询操作,从diff_coverage_report表中选取request_status为0,from为1的记录,并按update_time升序排列,限制返回结果数量为1个。

注意:

bash: mvn: command not found。

说明 127.0.0.1 服务上,没有配置mvn环境

解决办法:

在127.0.0.1 机器上,配置mvn环境

五、Super-jacoco原理

5.1 整体流程

为了支持增量覆盖率收集,我们需要做两件事情:**1)**获取不同版本代码diff文件;**2)**对jacoco进行二次开发,使其支持增量方法列表参数。

5.2 获取增量代码

主要流程:拉取master(参照分支)和feature(提测分支)代码,再通过JGit对两个分支源码进行比对,获取增量代码。以下为部分代码片段:

5.3. jacoco 二次改造,支持增量方法列表参数

JaCoCo 对 exec 的解析主要是在 Analyzer 类的 analyzeClass(final byte[] source) 方法。这里面会调用 createAnalyzingVisitor 方法,生成一个用于解析的 ASM 类访问器,继续跟代码,发现对方法级别的探针计算逻辑是在 ClassProbesAdapter 类的 visitMethod 方法里面。所以我们只需要改造 visitMethod 方法,使它只对提取出的每个类的新增或变更方法做解析,非指定类和方法不做处理。改造后的核心代码片段如下:

5.4. 执行

只需要在执行的mvn命令中加入-Djacoco.diffFile=变更方法列表,即可收集变更方法的代码覆盖率。如果不传入-Djacoco.diffFile或者Djacoco.diffFile参数为空,则默认收集全量覆盖率。

5.5. 报告输出

覆盖率报告如下图,在图中是某个 service 的实现类,在最新的代码中有23个方法,但是只会对变更或新增的5个方法进行覆盖率统计与显示:

5.6、架构

六、相关资料:

 滴滴开源Super-jacoco:java代码覆盖率收集平台 - 掘金

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1106217.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(3) OpenCV图像处理kNN近邻算法-识别摄像头数字

目录 一、代码简介 二、程序代码 三、使用的图片资源 1、图片digits.png

为什么价格监测要精确到款式

品牌在进行线上数据的监测时&#xff0c;首先需要对全网数据进行爬取&#xff0c;爬到的数据再做分析&#xff0c;最后再对有效的SKU数据进行监测&#xff0c;所以数据清洗很重要&#xff0c;采集到的基础数据更重要&#xff0c;只有数据采集全面了&#xff0c;才能进行全面的控…

python——loguru第三方日志管理模块

loguru第三方日志管理模块 loguru介绍日志等级日志保存日志过滤处理异常 loguru介绍 loguru是第三方库&#xff0c;拿来即用&#xff0c;不用太多的配置 安装&#xff1a;pip install loguru 日志等级 from loguru import loggerlogger.debug(这是一条调试消息&#xff01;)…

E054-web安全应用-Brute force暴力破解进阶

课程名称&#xff1a; E054-web安全应用-Brute force暴力破解进阶 课程分类&#xff1a; web安全应用 实验等级: 中级 任务场景: 【任务场景】 小王接到磐石公司的邀请&#xff0c;对该公司旗下的网站进行安全检测&#xff0c;经过一番检查发现该网站可能存在弱口令漏洞…

【Java笔试强训】Day1(100449-组队竞赛 、OR63 删除公共字符)

100449-组队竞赛 链接&#xff1a;组队竞赛 题目&#xff1a; 牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。 例如: 一个队伍三个…

修改ruoyi框架前端刷新页面时紫色的背景颜色

问题描述 最近在使用ruoyi的前后端分离框架&#xff0c;发现前端VUE页面刷新的时候&#xff0c;会出现加载的紫色页面&#xff0c;想要修改这个颜色&#xff0c;请看下面的教程。 修改教程 找到public/index.html&#xff0c;然后找到background为#7171C6这个颜色的代码&…

Redis 主从复制,哨兵,集群——(2)哨兵篇

目录 1. Redis 哨兵是什么&#xff1f; 2. Redis 哨兵有什么用&#xff1f; 2.1 主动监控 2.2 消息通知 2.3 故障转移 2.4 配置中心 3. Redis 哨兵数量配备要求 4. 哨兵配置文件详解 5. quorum 投票数详解 5.1 quorum 的含义 5.2 网络抖动导致主观下线 5.3 quorum …

Spring framework Day21:Spring AOP 注解结合配置类示例

前言 Spring AOP是一种强大的面向切面编程工具&#xff0c;它能够帮助我们更好地处理与核心业务逻辑无关的横切关注点。通过使用注解和配置类的方式&#xff0c;我们可以更加简洁和灵活地实现AOP。 本文将以一个示例来介绍如何结合注解和配置类来使用Spring AOP。通过这个示例…

解决Antd 二次封装表格的可编辑功能(editable table)不生效的问题

问题概述 使用了Antd Table组件&#xff0c;因为需要自定义的筛选功能&#xff0c;进行了二次封装。 之后加上了可编辑行功能&#xff0c;当点击编辑图标&#xff0c;发现表格并不会有任何变化。 代码&#xff1a; <Formcomponent{false}form{docInfoForm} ><CSTab…

正点原子嵌入式linux驱动开发——设备树下LED驱动

经过对设备树的学习以及驱动开发中常用的OF函数介绍&#xff0c;本篇笔记将之前的新字符设备驱动的LED&#xff0c;换成设备树形式。 设备树LED驱动原理 在之前的新字符设备驱动实验中&#xff0c;直接在驱动文件newchrled.c中定义有关寄存器物理地址&#xff0c;然后使用io_…

【前端学习】—Vue生命周期(十七)

【前端学习】—Vue生命周期&#xff08;十七&#xff09; 一、Vue生命周期 二、Vue父子组件生命周期调用顺序 三、Vue中在哪个生命周期内调用异步请求

【SpringCloud微服务项目实战-mall4cloud项目(4)】——mall4cloud-rbac

mall4cloud-rbac角色权限访问控制模块 系统架构与模块介绍系统架构rbac模型介绍 相关代码权限校验接口代码 补充 代码地址 github地址 fork自github原始项目 gitee地址 fork自gitee原始项目 系统架构与模块介绍 系统架构 从图中可以看到&#xff0c;微服务集群中&#xff0c;…

Netty系列教程之NIO基础知识

近30集的孙哥视频课程&#xff0c;看完一集整理一集来的&#xff0c;内容有点多&#xff0c;请大家放心食用~ 1. 网络通讯的演变 1.1 多线程版网络通讯 在传统的开发模式中&#xff0c;客户端发起一个 HTTP 请求的过程就是建立一个 socket 通信的过程&#xff0c;服务端在建立…

直线导轨在喷涂行业中的应用场景

直线导轨因其具有精度高、速度快、刚性强、使用寿命长等特点被广泛应用在各行各种中&#xff0c;其中&#xff0c;在喷涂行业中的应用最为广泛&#xff0c;以下是直线导轨在喷涂行业中的应用场景&#xff1a; 1、平面喷涂&#xff1a;直线导轨可以应用在各种机械加工的平面&…

将Sketch文件转化为PSD文件的简单在线工具!

设计工作不仅需要UI设计工具&#xff0c;还需要Photoshop。常见的UI设计工具Sketch与Photoshop软件不兼容。如果你想在实际工作中完成Sketch转psd&#xff0c;你需要使用其他软件进行转换。但是在转换过程中容易丢失文件&#xff0c;导致同样的工作需要重复多次才能完成&#x…

图论相关算法

一、迪杰斯特拉(Dijkstra)算法 迪杰斯特拉算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。这是一个贪心算法。 1.核心思想 &#xff08;1&#xff09;每次选中一个点&#xff0c;这个点满足两个条件&#xff1a; 未被选过距离最短 &#xff08;2&#xf…

Gazebo仿真 【ROS: noetic】

参考链接&#xff1a;《ROS机器人开发实践》_胡春旭 目标&#xff1a; 了解如何使用URDF文件创建一个机器人模型&#xff0c;然后使用xacro文件优化该模型&#xff0c;并且放置到rvizArbotiX或Gazebo仿真环境中&#xff0c;以实现丰富的ROS功能。 4.5 Gazebo仿真环境 1&#x…

kaggle新赛:UBC卵巢癌亚型分类和异常检测大赛【图像分类】

赛题名称&#xff1a;UBC Ovarian Cancer Subtype Classification and Outlier Detection (UBC-OCEAN) 赛题链接&#xff1a;https://www.kaggle.com/competitions/UBC-OCEAN 赛题背景 卵巢癌是女性生殖系统最致命的癌症。目前&#xff0c;卵巢癌诊断依赖病理学家评估亚型。…

MySQL的自增id会用完吗?用完怎么办?

MySQL作为最常用的关系型数据库&#xff0c;无论是在应用还是在面试中都是必须掌握的技能。 目录 一、MySQL自增主键会用完吗 二、MySQL自增主键用完会怎样 1.程序员自己设置的自增主键 2.程序员没有设置自增主键&#xff0c;mysql自动创建row_id 三、mysql中还有哪些自增…

IF: 22.1, 中科院1区TOP刊被剔除WOS (10月SCI/SSCI目录已更新)~

2023年10月17日&#xff0c;科睿唯安更新了Web of Science核心期刊目录。 此次更新后SCIE期刊目录共包含9485本期刊&#xff0c;SSCI期刊目录共包含3551本期刊。此次SCIE & SSCI期刊目录更新&#xff0c;与上次更新&#xff08;2023年9月&#xff09;相比&#xff0c;共有7…