Jacoco在K8S集群项目中部署小妙招

在项目交付过程中为了保证软件的质量,在交付之前通常会采用单元测试、接口测试、功能测试等手段对代码进行一次全方位的审查。怎样把case设计的全面、精简就成为了软件测试过程中最重要的命题,但在实际工作过程中,常常会遇到以下问题:

  1. 开发同学自测过程中,异常代码逻辑并未执行;
  2. 测试用例经过了反复的评审,但还是有部分异常情境未覆盖,漏测情况时有出现;
  3. 接口自动化测试case无法确定是否覆盖到了所有代码逻辑。

应对这种情况时,业界常常采用Jacoco来分析变更代码的覆盖率

Jacoco简介

Jacoco是一个开源的代码覆盖率工具,支持JVM,很多第三方的工具提供对Jacoco的集成,如Jenkins、IDEA、Sonar。

关于Jacoco的注入原理和注入方式,在官方文档上已经写得非常详细了,大家可以去参考一下~

Jaoco在统计功能测试覆盖率时,通常使用on-the-fly模式,在启动被测应用服务时,添加jvm参数 -javaagent,指定jar文件启动代理程序,代理程序在通过 Class Loader 装载一个 class 前判断是否需要注入 class 文件,将统计代码插入 class ,测试覆盖率分析就可以在 JVM 执行测试的过程中完成。然后使用官方提供的cli包去连接代理获取exec文件,根据exec文件生成代码覆盖率报告。

在K8S集群项目中应用Jacoco

我们使用Jacoco的场景主要是用于统计功能测试的代码覆盖率,被测系统部署在K8s集群中使用传统的部署的方式会遇到下列问题:

1、 集群内被测服务以TCP server方式启动Jacoco代理后,需要去连接该代理,但集群外不能直接访问集群内的代理,需要在集群配置对外暴露的端口,不灵活;
2、service对外暴露的IP可能会变化,采用ingress,配置比较复杂;
3、存在多个副本时,不易获取每个副本的覆盖率文件。

一种解决方案是被测服务以file方式启动Jacoco代理,就不需要去连接该代理,停掉服务后,就会生成覆盖率文件。但是服务停掉后,POD也被销毁了,无法取到生成的覆盖率文件。

第二种解决方案是被测服务以client的方式启动Jacoco代理,自己写一个服务端程序,部署在集群外,让代理主动来连接服务端,这样就解决了集群内外的通信问题,该方式在被测服务运行前要先启动服务端程序,否则应用服务连接不到服务端,会启动失败。服务端定时获取并生成覆盖率文件,不能事件触发,使用不方便。多人使用时,可能会混淆覆盖率文件。

但是,既然在容器内能运行jar包,就可以把jacococli放在容器内运行,然后去连接以TCP server方式启动的jacoco代理,获取覆盖率文件后,拷贝到集群外的jenkins服务器,生成覆盖率报告。该方案解决了与集群内的jacoco代理通信的问题,配置简单,大部分操作可以直接在jenkins执行。

配置流程

具体的配置步骤如下:

1. 修改jenkins上被测服务CD任务下的镜像制作脚本,由server_build.sh 修改为server_build.sh_jacoco,将jacoco的Agent包打到镜像中,用于步骤2在jar文件启动代理程序。

2. 登录jenkins服务器,进入对应服务的CI工程目录,在target目录下找到对应的版本包,eg:  /home/jenkins-new/jenkins_home/workspace/测试环境-k8s-后端-oneos-authentication-ci/target/

将版本包下载到本地,解压后修改bin目录下的start.sh,增加jvm参数 -

javaagent:/home/app/jacocoagent.jar=includes=**,output=tcpserver,port=11111,address=127.0.0.1*,append=true ,该参数用于启动jacoco代理。

注意:由于代码库中的start.sh未修改,每次执行CI操作后,需执行步骤2修改jvm启动参数

3. 在jenkin中新建任务,名称为”代码覆盖率-xxx“,在构建-执行shell中输入下列命令:

1)定义svc_name变量, 值为k8s中pod的名称前缀,如cms-portal-manager,可在portainer查看

svc_name="xxx"

2)在K8S集群的master节点执行copy_exec.sh。

ansible 10.11.12.13 -u app -b -m shell -a "bash /home/app/copy_exec.sh ${svc_name}"

该shell脚本主要是在每一个业务Pod内,使用jacoco.cli包去连接代理,获取覆盖率数据,生成exec文件,然后将文件从容器内拷贝出来。

3)将覆盖率数据文件从K8S主节点拷贝到Jenkins服务器中该任务对应的路径。

scp [email protected]:/tmp/${svc_name}/res-${svc_name}*.exec /var/jenkins_home/workspace/代码覆盖率-xxx/

4)将被测服务编译的class文件拷贝到该任务的当前路径

cp -r /var/jenkins_home/workspace/测试环境-cms-portal-manager-ci/cms-portal-manager/target/ ./

5)将被测服务的源码文件拷贝到该任务的当前路径

cp -r /var/jenkins_home/workspace/测试环境-cms-portal-manager-ci/cms-portal-manager/src/ ./

eg:

4. 在jenkins任务的invoke Ant,增加ant的配置,Properties中param1的值修改为当前任务名称,通过Ant,可以将多个exec文件合并。

5、在jenkins任务增加构建后操作,选择Record Jacoco coverage report,默认配置,保存退出。

6、对被测服务执行CD操作后,执行覆盖率任务,点击coverage report,查看覆盖率报告。

本文完~

{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/5443273/blog/5530648