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.该方法能模拟用户行为, ...
随机推荐
- HTTP 常见状态码【5种最最最常见的状态码】
HTTP 常见状态码 一.200 [ok] 一切正常 二.400 [Bad Request] 客户端 出现问题 需要注意:前端传入的参数与后台接收数据时的 参数名 必须保持一致 三.500 [Inte ...
- Go进程内存占用那些事(二)
0x01 最简单的Go程序 package main import ( "fmt" "time" ) func main() { fmt.Println(&qu ...
- 卡农 -- HNOI2011 -- DP&组合
卡农 -- \(HNOI2011\) $$luogu$$ $$HZOI$$ 题意 给定一个 集合 $ A= { 1 \le x \le n | x } $ , 求出其 \(m\) 个不相同的且不为空集 ...
- 修改 Ubuntu 文件夹为英文
如果你在安装 Ubuntu 时,语言选了中文,那么系统自动创建的文件夹也会是中文(下载.图片 等).有时这会造成不便.可以通过以下命令将文件夹改为英文: LANG=C LC_ALL=C xdg-use ...
- 安装 AWS CLI
安装 macOS 使用 Homebrew: brew install awscli 手动安装: curl "https://awscli.amazonaws.com/AWSCLIV2.pkg ...
- .NET 开源报表神器 Seal-Report
前言 Seal-Report 是一款.NET 开源报表工具,拥有 1.4K Star.它提供了一个完整的框架,使用 C# 编写,最新的版本采用的是 .NET 8.0 . 它能够高效地从各种数据库或 N ...
- vue打包项目版本号自加
原因 项目每次打包后都需要改动项目版本号,这个改动每次都需要在package.json中修改version,比较麻烦,到底有没有一种打包后版本号自加的办法. 方案 版本号自加其实可以使用fs修改文件来 ...
- 注册中心Nacos集群搭建
一提到注册中心,大家往往想到Zookeeper.或者Eureka.今天我们看看阿里的一款配置中心+注册中心的中间件--Nacos.有了它以后,我们的项目中的配置就可以统一从Nacos中获取了,而且Sp ...
- 为何不要随便用from xx import *
新单位,新工作,远程办公,你想想有多麻烦吧. 一块块看每个模块的详细功能. 看到一个函数,返回值也是一个函数,这本来没啥难的,但是文件里只出现一次.怎么都找不到来自哪个文件,后来全项目搜才找到,原来来 ...
- DOM – MutationObserver
介绍 它和 IntersectionObserver, ResizeObserver 差不多, 都是观察 element 变化的. 它可以观察元素的 attribute 增加, 移除, 修改, app ...