Go服务自动触发单元测试覆盖率
一、用到的工具
- Gitlab
- Jenkins
- Shell
- go test
二、实现原理
在gitlab上配置jenkins的webhook,当有代码变更时自动触发jenkins构建job,job内的shell脚本负责把覆盖率报告以钉钉群通知的方法发送出去。

三、Jenkins job配置

点击上图中的“高级”,出现下图后,点击“Generate”,生成Secret token。

四、Gitlab配置webhook

五、Shell脚本

touch last_num.txt
fi
#存储本次.go文件和_test.go文件的个数,作为上次数据
echo $this_time_go_num > ./this_time_go_num.txt
echo $this_time_test_go_num > ./this_time_test_go_num.txt
echo $this_time_per > ./this_time_per.txt
#获取上次的.go文件数,如果没有则创建文件
if test -e last_time_go_num.txt
then
last_time_go_num=$(cat last_time_go_num.txt)
echo $last_time_go_num
else
touch last_time_go_num.txt
fi
#获取上次的test.go文件数,如果没有则创建文件
if test -e last_time_test_go_num.txt
then
last_time_test_go_num=$(cat last_time_test_go_num.txt)
echo $last_time_test_go_num
else
touch last_time_test_go_num.txt
fi
#获取上次的per,如果没有则创建文件
if test -e last_time_per.txt
then
last_time_per=$(cat last_time_per.txt)
echo $last_time_per
else
touch last_time_per.txt
fi
#计算两次.go文件数的差
go_num_diff=`expr $this_time_go_num - $last_time_go_num`
echo $go_num_diff
#计算两次test.go文件数的差
test_go_num_diff=`expr $this_time_test_go_num - $last_time_test_go_num`
echo $test_go_num_diff
#计算两次占比的差
this_time_test_go_num_init=$(printf "%d" $(($this_time_test_go_num*100/$this_time_go_num)))
last_time_test_go_num_init=$(printf "%d" $(($last_time_test_go_num*100/$last_time_go_num)))
per_diff=$(printf "%d%%\n" $(($this_time_test_go_num_init-$last_time_test_go_num_init)))
echo $per_diff
cd -
echo "生成Html报告"
go tool cover -html=cover.out -o coverage.html
cp coverage.html /Users/xes/CI/reports/xxx-unitcover/a_this_time_html_report/this_time_coverage.html
# 构造知音楼通知text的内容
cd $this_path
this_time=$(cat this_num.txt)
last_time=$(cat last_num.txt)
now=$(echo $this_time|cut -b 1,2,3,4)
last=$(echo $last_time|cut -b 1,2,3,4)
change=$(echo | awk "{print $now - $last}")
# 设置secret
secret=""
# 设置Webhook
xxx_robot_path=
access_token=
# URL Encode 函数
function urlencode() {
local LANG=C
local length="${#1}"
i=0
while :
do
[ $length -gt $i ]&&{
local c="${1:$i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
}||break
let i++
done
}
# 执行函数
function run() {
# 获取时间戳
cur_sec_and_ns=`date '+%s-%N'`
cur_sec=${cur_sec_and_ns%-*}
cur_ns=${cur_sec_and_ns##*-}
cur_timestamp=$((cur_sec*1000+cur_ns/1000000))
echo "当前时间戳:"$cur_timestamp
# 获得签名
sign=`echo -n -e "$cur_timestamp\n$secret" | openssl dgst -sha256 -hmac $secret -binary | base64`
echo "加密后签名:"$sign
# 对签名进行 urlencode
sign_urlencode=`urlencode $sign`
echo "urlencode 后签名:"$sign_urlencode
url_action=""
url_encode=`urlencode $url_action`
echo $url_encode
request_url=$yach_robot_path"×tamp="$cur_timestamp"&sign="$sign_urlencode
echo "最终请求的 URL:"$request_url
curl -X POST \
$request_url \
-H 'content-type: application/json' \
-d '{
"msgtype": "action_card",
"action_card": {
"title": "单测统计xxx",
"markdown": "### *_test.go占比(不含vendor) \n| 统计----------- | 本次------ | 上次------ | 新增 | \n| :--- | :--- | :--- | :--- | \n| .go | '"$this_time_go_num"' | '"$last_time_go_num"' | '"$go_num_diff"' | \n| test.go | '"$this_time_test_go_num"' | '"$last_time_test_go_num"' | '"$test_go_num_diff"' | \n| test.go/.go | '"$this_time_per"' | '"$last_time_per"' | '"$per_diff"' | \n### *_test.go覆盖率(平均值) \n| 本次------ | 上次------ | 差值 | \n| :--- | :--- | :--- | \n| '"$this_time"' | '"$last_time"'| '"$change"' | \n \n#### 本次&上次覆盖率HTML报告(点击打开) \n'"$url_action"'",
"image": "https://sentry.io/_assets/screenshots/features-page-dash-12c65431808e7d8daf234a096446c1f0da311a0f3bcec5352e28bda60136fb16.jpg",
"content_title": "xxx单测覆盖率统计",
"single_title": "点击此处,在侧边栏查看HTML报告",
"single_url": ""
}
}'
}
run
#把本次的覆盖率赋值给上次
cp this_num.txt last_num.txt
#把本次的.go文件值给上次
cp this_time_go_num.txt last_time_go_num.txt
#把本次的test.go文件值给上次
cp this_time_test_go_num.txt last_time_test_go_num.txt
#把本次的per值给上次
cp this_time_per.txt last_time_per.txt
#用本次的HTML报告覆盖上次的HTML报告
cd ..
cp a_this_time_html_report/this_time_coverage.html b_last_time_html_report/last_time_coverage.html
避坑:
在slave机器上git clone遇到一个小坑,如下图:

原因是slave机器上的git默认账号对此gitlab仓库权限不足,解决方法是给git clone命令加上username和password

六、Go test 命令
如步骤五中所示,用到2个go test命令,如下:
go test ./... -coverprofile=cover.out # 生成.out文件
go tool cover -html=cover.out -o coverage.html # 生成Html报告
七、钉钉群通知
钉钉机器人配置:
钉钉机器人的安全设置方式有3种,我们这里选择方式一“自定义关键词”

添加钉钉机器人:

请求字段说明:

注意:请求的content中(content即link的值,也就是在text或title中包含)必须包含钉钉机器人的“自定义关键词”,比如我们curl请求中就包含了“单元测试”,否则会报如下图的错误

八、通知消息展示
钉钉群接收到的通知消息:

Go服务自动触发单元测试覆盖率的更多相关文章
- 使用coverage工具统计python单元测试覆盖率
Coverage简介 Coverage是一种用于统计Python代码覆盖率的工具,通过它可以检测测试代码对被测代码的覆盖率如何.Coverage支持分支覆盖率统计,可以生成HTML/XML报告. 官方 ...
- [转载] JaCoCo:分析单元测试覆盖率的利器
转载自http://www.ibm.com/developerworks/cn/java/j-lo-jacoco/和http://www.cnblogs.com/chenfengmugu/p/4937 ...
- 单元测试系列之一:如何使用JUnit、JaCoCo和EclEmma提高单元测试覆盖率
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6726664.html -----如 ...
- zabbix系列(九)zabbix3.0实现自动触发zabbix-agent端shell脚本任务
zabbix实现自动触发远程脚本执行命令 Zabbix触发器(trigger)达到阀值后会有动作(action)执行:发送告警信息或执行远程命令 环境 Server:基于centos6.5 final ...
- rsync+inotify实现实时同步,自动触发同步文件
本文参考来自:http://chocolee.blog.51cto.com/8158455/1400596 我的需求和他的略有不同,同时做了一下更改,如下: 需求:两台机器相互为主备,搭建相同的两个服 ...
- maven install时自动施行单元测试
maven install时自动执行单元测试 1.maven-surefire-plugin简介 Maven本身并不是一个单元测试框架,它只是在构建执行到特定生命周期阶段的时候,通过插件来执行JUni ...
- Jenkins集成jacoco收集单元测试覆盖率
Jenkins集成jacoco收集单元测试覆盖率 2020-02-28 目录 0 整体思路1 Jenkins创建JacocoIntegrateTestDemo项目2 配置源码管理3 配置Build4 ...
- Jenkins 自动触发执行的配置
1. 两种触发方式 2. jenkins 和 github 同步配置 ngrok 安装 webhook 配置 1. 两种触发条件 Jenkins 中建立的任务是可以设置自动触发,更进一步的实现自动化. ...
- TeamCity : 自动触发 Build
创建了 build 的配置以后,您既可以手动点击 "Run" 按钮来触发一次 build 过程,也可以通过 Triggers 配置实现自动触发 build 过程.一个 trigge ...
- 原生js自动触发事件
熟悉jquery的童鞋都知道在jq中有一个方法可以自动触发事件,那就是trigger(),那么通过原生js又怎么模拟触发呢? js中添加一个主动触发事件的方法有dispatch.该方法能模拟用户行为, ...
随机推荐
- [学习笔记] LCA - 图论
[NOIP2013 提高组] 货车运输 最大生成树+LCA+倍增 好家伙,这道题我写了一个晚上,调了两个晚上,对于这道题我颇有感触.但这道题确实好,实实在在的蓝题,让我发现了许多关于LCA的问题. 首 ...
- 下一代浏览器和移动自动化测试框架:WebdriverIO
1.介绍 今天给大家推荐一款基于Node.js编写且号称下一代浏览器和移动自动化测试框架:WebdriverIO 简单来讲:WebdriverIO 是一个开源的自动化测试框架,它允许测试人员使用 No ...
- SimpleRAG:基于WPF与Semantic Kernel实现的一个简单的RAG应用
SimpleRAG介绍 SimpleRAG是基于WPF与Semantic Kernel实现的一个简单的RAG应用,可用于学习与理解如何使用Semantic Kernel构建RAG应用. GitHub地 ...
- 【原创】vagrant up 异常报错,出现 There was an error while executing `VBoxManage` 的解决方法
最近在使用 vagrant homestead 时,不小心在虚拟机上使用了 exit 命令退出虚拟机,导致再使用 vagrant up 时出现以下错误: Bringing machine 'larav ...
- Ubuntu 24.04 安装 Python 2.7
Ubuntu 24.04 对 Python 2.7 的维护已经停止了,因此 Python 2.7 已从 Ubuntu 24.04 软件包移除.如果想要安装 Python 2.7,需要我们自己从 Pyt ...
- Centos8下搭建私人开源网盘NextCloud步骤及使用(基于LAMP)
简介:Nextcloud是一款开源免费的私有云存储网盘项目,可以让你快速便捷地搭建一套属于自己或团队的云同步网盘,从而实现跨平台跨设备文件同步.共享.版本控制.团队协作等功能.它的客户端覆盖了Wind ...
- 一文搞懂 == 、equals和hashCode
面试的时候,经常会被问到==和equals()的区别是什么?以及我们也知道重写equals()时候必须重新hashCode().这是为什么?既然有了hashCode()方法了,JDK又为什么要提供eq ...
- 【Azure Developer】上手 The Best AI Code "Cursor" : 仅仅7次对话,制作个人页面原型,效果让人惊叹!
AI Code 时代早已开启,自己才行动.上手一试,让人惊叹.借助这感叹的情绪,把今天操作Cursor的步骤记录下来,也分享给大家. 推荐大家上手一试,让你改变! 准备阶段 下载 Cursor(htt ...
- Docker 知识梳理及其安装使用
Docker 介绍 Docker 是一个强大的工具,用于高效开发.打包和部署应用程序.Docker 是一种容器管理服务.Docker 于 2013 年发布.它是开源的,可用于 Windows.macO ...
- VulnStack-红日靶机二
红日靶机二 环境搭建 只需要把虚拟机的 host-only(仅主机)网卡改为 10.10.10.0 网段,如下配置 把 NAT 网卡,改为 192.168.96.0 网段,如下 首先恢复到 v1.3 ...