【Devops】【测试左移】jacoco代码覆盖率统计的几个脚本
2022-09-27 15:47 码上起舞 阅读(217) 评论(0) 编辑 收藏 举报背景、
代码覆盖率统计,本来有更简单的方式,在mvn或者pom中加插件即可,but,历史代码历史工程太多,直接改pom需要工作量较大,要无感知集成代码覆盖率检查,故整理了这几个脚本来结合jenkins工程使用
一、在测试服务器部署路径下注入jacoco
insert.sh是用于将jacoco.sh中的内容打桩到catalina.sh的脚本中,需传一个参数,为服务器的ip地址。使用方式为sh insert.sh <server_ip>
#!/bin/bash #该脚本用于将jacoco的代理内容(jacoco.sh)插入catalina.sh的启动脚本中 #使用方式:sh insert.sh 10.xx.xx.xx #jacoco,默认使用9999端口的tcp方式 if [ $# -ne 1 ];then echo "Usage:$0 filename" exit 1 fi #将ip写入jacoco.sh ip=$1 sed -i "s/address=/&$ip/" jacoco.sh #cat jacoco.sh #将jacoco内容插入catalina.sh jagent=`cat -n catalina.sh |grep -i "javaagent"` echo $jagent if [[ -z $jagent ]];then #在第一个java_opts变量定义的后面加入jacoco的代理内容 row=`cat -n catalina.sh |grep -i "JAVA_OPTS="|awk '{print $1}'|sed -n "1"P` sed -i "${row}r jacoco.sh" catalina.sh echo "|||execute insert.sh finished" else echo "|||jacoco agent is already insert in,no need to execute insert.sh" fi
二、将第一步需要打桩的代码内容汇总到jacoco.sh中
jacoco.sh 是jacoco agent的打桩具体内容,address为空,动态写入,默认端口为9999
if [ "$1" = "start" ];then JAVA_COCO="-javaagent:jacocoagent.jar=includes=*,output=tcpserver,port=9999,address=" JAVA_OPTS="$JAVA_OPTS $JAVA_COCO" echo $JAVA_OPTS fi
三、在jenkins服务器执行jaco_exec并收集报告
jacoco_exec.sh
#!/bin/bash #该脚本用于将生成jacoco.exec文件并生成xml报告 #jacoco.exec文件在当前jenkins工程的workspace下的jacoco_exec文件夹下 #初始目录均为$WORKSPACE,需传4个参数,ip地址+classes地址+src源码地址+工作空间地址 #使用方式:sh jacoco_exec.sh 10.xx.xx.xx workspace/code/ workspace/code/ workspace #src和class地址会根据传参进行遍历,传工程code目录即可 #jacoco,默认使用9999端口的tcp方式 if [ $# -ne 4 ];then echo "Usage:$0 envip classes srcs workspace" exit 1 fi server_ip=$1 classes_dir=$2 src_dir=$3 workspace=$4 if [ -f "$workspace/jacoco_exec/jacoco.exec" ];then rm -rf $workspace/jacoco_exec/jacoco.exec fi sleep 3 #遍历$2中所有的src目录和classes目录 class_arr=() src_arr=() #arr[${#arr[*]}] #遍历src目录和classes目录 function read_dir(){ for file in `ls $1` #注意此处这是两个反引号,表示运行系统命令 do if [ -d $1"/"$file ];then if [[ $file = "target" ]];then if [[ -d $1"/src" ]];then class_arr[${#class_arr[*]}]=$1"/target/classes/com" src_arr[${#src_arr[*]}]=$1"/src/main/java/" fi else read_dir $1"/"$file fi fi done } read_dir $classes_dir echo ${class_arr[*]} echo ${src_arr[*]} #生成jacoco.exec文件 java -jar /data/jacoco/jacoco/lib/jacococli.jar dump --address $server_ip --port 9999 --destfile $workspace/jacoco_exec/jacoco.exec #生成xml报告用于丰声发消息 num=${#class_arr[@]} num=`expr $num - 1` #每个目录生成report.xml reportlist="" for i in $(seq 0 ${num}); do reportlist="$reportlist $workspace/report$i.xml" java -jar /data/jacoco/jacoco/lib/jacococli.jar report $workspace/jacoco_exec/jacoco.exec --classfiles ${class_arr[$i]} --sourcefiles ${src_arr[$i]} --xml $workspace/report$i.xml done #java -jar /data/jacoco/jacoco/lib/jacococli.jar report $workspace/jacoco_exec/jacoco.exec --classfiles $classes_dir --sourcefiles $src_dir --xml $workspace/report.xml echo $reportlist #返回覆盖率结果 covmessage=$(python3 /data/llm/git/gis-qrcts-core-mpc-qa/SF_Jenkins_scripts/script_for_jacoco/get_jacoco_coverity.py $reportlist) echo $covmessage
四、解析报告中的覆盖率值脚本
get_jacoco_coverity.py 是解析覆盖率的xml文件,将总体的class和method覆盖率计算出来,用于发消息通知。使用方式为python3 get_jacoco_coverity.py report.xml
#!/usr/bin/env python # -*- coding: UTF-8 -*- ''' date:2021/3/15 description: ''' import sys try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET import sys class Jacoverty: def get_javacoco_coverity(self,filenames): '''获取jacoco的 xml文件覆盖率统计数据''' class_cov=class_total=class_miss=0 method_cov=method_total=method_miss=0 for filename in filenames: tree = ET.parse(filename) root = tree.getroot() for counter in root.findall("counter"): covtype = counter.get("type") if "CLASS" == covtype: class_miss += int(counter.get("missed")) class_cov += int(counter.get("covered")) if "METHOD" == covtype: method_miss += int(counter.get("missed")) method_cov += int(counter.get("covered")) class_total += class_miss + class_cov method_total += method_miss+method_cov class_coverty = format(float(class_cov)/float(class_total),'.0%') method_coverty = format(float(method_cov) / float(method_total), '.0%') # print(class_total,class_cov,method_total,method_cov) str = f'Coverage Summary = {"CLASS"}:{class_coverty};{"METHOD"}:{method_coverty};' print(str) return str if __name__ == '__main__': files = sys.argv[1:] # files = ["reportxml2.xml","reportxml.xml"] Jacoverty().get_javacoco_coverity(files)
五、举例
jenkins工程使用示例
#拷贝jacoco包和脚本到bin目录
/usr/bin/scp -i ~/.ssh/id_rsa -P22 /data/script_for_jacoco/jacoco.sh /data/script_for_jacoco/insert.sh appdeploy@$server_ip:/data/server/bin
/usr/bin/scp -i ~/.ssh/id_rsa -P22 /data/jacoco/jacoco/lib/jacocoagent.jar appdeploy@$server_ip:/data/server/bin
sleep 100 #生成覆盖率文件 classes=${WORKSPACE}/code srcs=${WORKSPACE}/code source /data/script_for_jacoco/jacoco_exec.sh $server_ip $classes $srcs ${WORKSPACE} echo $covmessage
#注释,如果不用上面封装的脚本,则用下面的一步一步执行,核心原理一样 #hostip="xx.xx.xx.xx" #cd $WORKSPACE #if [ -f "./jacoco_exec/jacoco.exec" ];then # rm -rf ./jacoco_exec/jacoco.exec #fi #sleep 30 #java -jar /data/acoco/jacoco/lib/jacococli.jar dump --address $hostip --port 9999 --destfile ./jacoco_exec/jacoco.exec #java -jar /data/jacoco/jacoco/lib/jacococli.jar report ./jacoco_exec/jacoco.exec --classfiles ./code/databoard-boot/target/classes/com --sourcefiles ./code/databoard-boot/src/main/java/ --xml ./report.xml #cd /data/script_for_jacoco #ls #covmessage=$(python3 get_jacoco_coverity.py $WORKSPACE/report.xml) #pwd #ls
----------------------
认真工作
快乐生活
----------------------
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期