在项目交付过程中为了保证软件的质量,在交付之前通常会采用单元测试、接口测试、功能测试等手段对代码进行一次全方位的审查。怎样把case设计的全面、精简就成为了软件测试过程中最重要的命题,但在实际工作过程中,常常会遇到以下问题:
- 开发同学自测过程中,异常代码逻辑并未执行;
- 测试用例经过了反复的评审,但还是有部分异常情境未覆盖,漏测情况时有出现;
- 接口自动化测试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执行。
配置流程
具体的配置步骤如下:
- 修改jenkins上被测服务CD任务下的镜像制作脚本,由server_build.sh 修改为server_build.sh_jacoco,将jacoco的Agent包打到镜像中,用于步骤2在jar文件启动代理程序。
- 登录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启动参数
- 在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 app@10.11.12.13:/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:
- 在jenkins任务的invoke Ant,增加ant的配置,Properties中param1的值修改为当前任务名称,通过Ant,可以将多个exec文件合并。
5、在jenkins任务增加构建后操作,选择Record Jacoco coverage report,默认配置,保存退出。
6、对被测服务执行CD操作后,执行覆盖率任务,点击coverage report,查看覆盖率报告。
本文完~
版权归原作者 中移OneOS 所有, 如有侵权,请联系我们删除。