【集成测试覆盖率实践】tomcat+jenkins+cobertura显示代码覆盖率

文章目录

      • 1 基础知识了解
        • 1.1 代码覆盖率及常用工具对比
        • 1.2 cobertura原理
      • 2 环境安装准备
        • 2.1 tomcat安装
        • 2.2 maven安装
        • 2.3 jenkins安装
        • 2.4 jenkins需要的插件
        • 2.5 jenkins job配置
      • 3 cobertura实践
        • 3.0 下载cobertura
        • 3.1 插桩instrument
        • 3.2 部署子项目
        • 3.3 执行case
        • 3.2 merge
        • 3.3 生成报告并展示
      • 4 遇到的问题
        • 4.1 cobertura-instrument.sh执行报错Could not find or load main class
        • 4.1 cobertura-instrument.sh执行时部分文件报错unable to instrument file

好记性不如烂笔头,写下此文章,一是给需要的小伙伴一点点参考;二是给自己做个备忘。

实际使用场景说明:
1、源代码与测试代码分离;
2、源代码有多个模块,生成的覆盖率是各模块的覆盖率,需要进行合并;
3、针对全量覆盖率,增量覆盖率暂未实践

主要是在cobertura实践一节。前面环节已经准备好的小伙伴,可以直接看cobertura实践。

1 基础知识了解

1.1 代码覆盖率及常用工具对比

添不同覆盖率工具的比较

1.2 cobertura原理

cobertura原理

2 环境安装准备

2.1 tomcat安装

JDK+tomcat安装配置

2.2 maven安装

linux下MAVEN配置

2.3 jenkins安装

首先确保JDK、tomcat已经安装成功,并且tomcat可成功访问。
jenkins有异常可查看日志apache-tomcat-8.5.47/logs/catalina.out看看报什么错误。

// 1、下载jenkins的war包,并放于tomcat的webapps目录下
# cd /usr/local/apache-tomcat-8.5.47/webapps
# wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war

// 2、重启tomcat
# cd /usr/local/apache-tomcat-8.5.47/bin
# sh startup.sh

// 3、访问jenkins
浏览器输入http://ip:8083/jenkins (输入对应的ip、端口即可)

// 4、首次启动,需要输入初始密码
页面上提示了初始密码的保存位置,在对应目录下打开文件拷贝密码。成功进入jenkins

// 5、需要选择安装哪些插件,先勾选通用的插件(如git、maven等),其他需要安装的插件,请参看2.4小节

2.4 jenkins需要的插件

如果jenkins官网插件下载不下来,可以在清华的镜像网站上下载:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/

插件名称 job配置中的对应选项 用途 配置参考文档
cobertura.hpi 构建后操作中,Publish Cobertura Coverage Report 生成cobertura覆盖率报告用的 https://blog.csdn.net/yaominhua/article/details/40684647
credentials.hpi jenkins左侧边栏,Credentials 凭据管理 https://www.jianshu.com/p/22cc65462e8b
git-client.hpi、git-server.hpi、git.hpi、github-api.hpi、github.hpi、github-branch-source.hpi 源码管理中,Git 配置源码git 这几个插件有依赖关系,需要按一定顺序安装。如果安装失败,看一下失败原因,依赖顺序是什么。
groovy-postbuild.hpi 构建后操作,Groovy Postbuild 我的主要途是获取job的构建参数 样例:branchname=manager.build.buildVariables.get(“branchName”) manager. addInfoBadge(“分支信息为:”+ branchname +"\n")
jsch.hpi
localization-zh-cn.hpi jenkins汉化插件 自行网上找配置文档
maven-plugin.hpi maven插件
multiple-scms.hpi 源码管理,Multiple SCMs 多源码库管理 由于我的工程里有多个源码库,所以有这个插件,单个git库的不需要这个
parameterized-trigger.hpi 构建后操作,Trigger parameterized build on other projects 当前job完成后,触发新的job(可传递当前job的参数到新的job) 自行网上找配置文档
publish-over-ssh.hpi Send files or execute commands over SSH 可通过ssh的方式向机器上传送文件
run-condition.hpi
script-security.hpi
ssh-credentials.hpi

2.5 jenkins job配置

说一下大概要配置哪些,具体的配置可自行网上搜索。
1、配置凭据;
2、配置部署服务的job;跑测试代码的job;跑覆盖率的job;
3、有的涉及到准备工作或收尾的:可在job中配置执行shell;或通过ssh 执行已经在服务器上的脚本。

3 cobertura实践

小建议:jenkins上配置cobertura命令行之前,先在本地执行一下,确认是否能执行成功;如果执行失败,可以快速的看到失败原因是什么,有针对性的解决。

请先了解cobertura基本命令:https://github.com/cobertura/cobertura/wiki/Command-Line-Reference

主要思路:
1、对生成的class文件进行插桩操作;
2、将插桩后的class文件重新打包成jar包;
3、将插桩后的jar包替换到项目对应的lib目录;
4、执行测试case,让case执行测试插桩后的代码,并生成覆盖率文件;
5、将多个模块的覆盖率文件合并;
6、生成报告并在jenkins上展示;

3.0 下载cobertura

https://github.com/cobertura/cobertura
下载需要的版本:
http://repo1.maven.org/maven2/net/sourceforge/cobertura/cobertura/2.1.1/

3.1 插桩instrument

# cd 父项目目录/子项目目录下
// 1、对子项目中进行打包
# mvn package -B -e -U -am -pl 子项目名称
// 2、对打包生成的class插桩并替换掉原来class,并在指定目录下生成cobertura.ser文件(即用插桩后的class文件替换未插桩的class文件)
# cobertura-instrument.sh  子项目目录/target/classes  --auxClasspath 子项目目录/output/lib  --datafile 覆盖率文件目录/cobertura.ser
// 3、重新生成子项目的jar包
# mvn jar:jar
// 4、将子项目jar包放到产出物的lib目录下
# cp 子项目名.jar output/lib/

3.2 部署子项目

// 1、将产出物拷贝到部署目录
# cp -r 子项目目录/output/*  部署目录/
// 2、将cobertura的jar包拷贝到lib目录
# cp cobertura目录/cobertura.jar 部署目录/lib/

3.3 执行case

case执行昌,会将覆盖率信息写入到cobertura.ser中,最后是通过对比cobertura.ser和源码得出覆盖率的

// 1、执行集成case(另一个工程,和源码是分开的)
# cd case工程目录
# java -cp .:./target/case.jar:cobertura目录/cobertura.jar  -Dnet.sourceforge.cobertura.datafile=覆盖率文件目录/cobertura.ser 测试case入口代码

3.2 merge

// 2、将各模块的覆盖率文件合并到一个文件中
# sh cobertura目录/cobertura-merge.sh --datafile 总的覆盖率文件目录/cobertura.ser 模块A的覆盖率文件目录/cobertura.ser  模块B的覆盖率文件目录/cobertura.ser

3.3 生成报告并展示

// 2、生成报告并在展示
# sh cobertura目录/cobertura-report.sh --datafile 总的覆盖率文件目录/cobertura.ser --destination ${WORKSPACE}/覆盖率报告目录 --format xml 源码目录/src/main/java

4 遇到的问题

4.1 cobertura-instrument.sh执行报错Could not find or load main class

问题
执行插桩命令时,会报错:

# sh cobertura-instrument.sh  [yourProjectSourcePath]/target/classes
……
Could not find or load main class net.sourceforge.cobertura.instrument.InstrumentMain
……

原因
命令是dos格式的,需要转成unix格式
解决
按如下方式将cobertura/bin目录下的sh文件转为unix,重新执行插桩操作,不报错了。

// 1、安装dos2unix工具
# yum install -y dos2unix
// 2、将cobertura-instrument.sh转为unix格式
# dos2unix cobertura-instrument.sh
// 3、将cobertura/bin目录下的所有sh文件都转为unix格式(后续还会用到merge、report等)
# dos2unix *.sh

4.1 cobertura-instrument.sh执行时部分文件报错unable to instrument file

问题
执行插桩命令时,部分文件会报如下错误:

# sh cobertura-instrument.sh  [yourProjectSourcePath]/target/classes
……
unable to instrument file  子项目目录/target/classes/XXX.class
java.lang.RuntimeException: null
	at org.objectweb.asm.MethodVisitor.visitParameter(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
	at org.objectweb.asm.ClassReader.b(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
	at org.objectweb.asm.ClassReader.accept(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
	at org.objectweb.asm.ClassReader.accept(Unknown Source) ~[asm-5.0.1.jar:5.0.1]
	at net.sourceforge.cobertura.instrument.CoberturaInstrumenter.instrumentClass(CoberturaInstrumenter.java:161) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CoberturaInstrumenter.instrumentClass(CoberturaInstrumenter.java:129) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CoberturaInstrumenter.addInstrumentationToSingleClass(CoberturaInstrumenter.java:243) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentationToSingleClass(CodeInstrumentationTask.java:299) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:308) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.addInstrumentation(CodeInstrumentationTask.java:317) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.CodeInstrumentationTask.instrument(CodeInstrumentationTask.java:90) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.dsl.Cobertura.instrumentCode(Cobertura.java:74) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.InstrumentMain.instrument(InstrumentMain.java:82) [cobertura-2.1.1.jar:2.1.1]
	at net.sourceforge.cobertura.instrument.InstrumentMain.main(InstrumentMain.java:99) [cobertura-2.1.1.jar:2.1.1]
……

原因
目前我也没弄清楚报错的真实原因是什么。
网上找了好多解决办法,都没有解决我的问题;
后来我仔细看了cobertura官方的命令行文档,推测可能是依赖的lib包的原因,就加了参数–auxClasspath试了下,好了。
解决

# sh cobertura-instrument.sh  子项目目录/target/classes  --auxClasspath 子项目目录/output/lib

参考文档
非常感谢以下文章给予的帮助:
jar包和插件下载:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/
cobertura原理:https://blog.csdn.net/kittyboy0001/article/details/25078449
cobertura官方文档:https://github.com/cobertura/cobertura/wiki/Command-Line-Reference

你可能感兴趣的:(java)