一、用到的工具

  • 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"&timestamp="$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服务自动触发单元测试覆盖率的更多相关文章

  1. 使用coverage工具统计python单元测试覆盖率

    Coverage简介 Coverage是一种用于统计Python代码覆盖率的工具,通过它可以检测测试代码对被测代码的覆盖率如何.Coverage支持分支覆盖率统计,可以生成HTML/XML报告. 官方 ...

  2. [转载] JaCoCo:分析单元测试覆盖率的利器

    转载自http://www.ibm.com/developerworks/cn/java/j-lo-jacoco/和http://www.cnblogs.com/chenfengmugu/p/4937 ...

  3. 单元测试系列之一:如何使用JUnit、JaCoCo和EclEmma提高单元测试覆盖率

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢!   原文链接:http://www.cnblogs.com/zishi/p/6726664.html -----如 ...

  4. zabbix系列(九)zabbix3.0实现自动触发zabbix-agent端shell脚本任务

    zabbix实现自动触发远程脚本执行命令 Zabbix触发器(trigger)达到阀值后会有动作(action)执行:发送告警信息或执行远程命令 环境 Server:基于centos6.5 final ...

  5. rsync+inotify实现实时同步,自动触发同步文件

    本文参考来自:http://chocolee.blog.51cto.com/8158455/1400596 我的需求和他的略有不同,同时做了一下更改,如下: 需求:两台机器相互为主备,搭建相同的两个服 ...

  6. maven install时自动施行单元测试

    maven install时自动执行单元测试 1.maven-surefire-plugin简介 Maven本身并不是一个单元测试框架,它只是在构建执行到特定生命周期阶段的时候,通过插件来执行JUni ...

  7. Jenkins集成jacoco收集单元测试覆盖率

    Jenkins集成jacoco收集单元测试覆盖率 2020-02-28 目录 0 整体思路1 Jenkins创建JacocoIntegrateTestDemo项目2 配置源码管理3 配置Build4 ...

  8. Jenkins 自动触发执行的配置

    1. 两种触发方式 2. jenkins 和 github 同步配置 ngrok 安装 webhook 配置 1. 两种触发条件 Jenkins 中建立的任务是可以设置自动触发,更进一步的实现自动化. ...

  9. TeamCity : 自动触发 Build

    创建了 build 的配置以后,您既可以手动点击 "Run" 按钮来触发一次 build 过程,也可以通过 Triggers 配置实现自动触发 build 过程.一个 trigge ...

  10. 原生js自动触发事件

    熟悉jquery的童鞋都知道在jq中有一个方法可以自动触发事件,那就是trigger(),那么通过原生js又怎么模拟触发呢? js中添加一个主动触发事件的方法有dispatch.该方法能模拟用户行为, ...

随机推荐

  1. HTTP 常见状态码【5种最最最常见的状态码】

    HTTP 常见状态码 一.200 [ok] 一切正常 二.400 [Bad Request] 客户端 出现问题 需要注意:前端传入的参数与后台接收数据时的 参数名 必须保持一致 三.500 [Inte ...

  2. Go进程内存占用那些事(二)

    0x01 最简单的Go程序 package main import ( "fmt" "time" ) func main() { fmt.Println(&qu ...

  3. 卡农 -- HNOI2011 -- DP&组合

    卡农 -- \(HNOI2011\) $$luogu$$ $$HZOI$$ 题意 给定一个 集合 $ A= { 1 \le x \le n | x } $ , 求出其 \(m\) 个不相同的且不为空集 ...

  4. 修改 Ubuntu 文件夹为英文

    如果你在安装 Ubuntu 时,语言选了中文,那么系统自动创建的文件夹也会是中文(下载.图片 等).有时这会造成不便.可以通过以下命令将文件夹改为英文: LANG=C LC_ALL=C xdg-use ...

  5. 安装 AWS CLI

    安装 macOS 使用 Homebrew: brew install awscli 手动安装: curl "https://awscli.amazonaws.com/AWSCLIV2.pkg ...

  6. .NET 开源报表神器 Seal-Report

    前言 Seal-Report 是一款.NET 开源报表工具,拥有 1.4K Star.它提供了一个完整的框架,使用 C# 编写,最新的版本采用的是 .NET 8.0 . 它能够高效地从各种数据库或 N ...

  7. vue打包项目版本号自加

    原因 项目每次打包后都需要改动项目版本号,这个改动每次都需要在package.json中修改version,比较麻烦,到底有没有一种打包后版本号自加的办法. 方案 版本号自加其实可以使用fs修改文件来 ...

  8. 注册中心Nacos集群搭建

    一提到注册中心,大家往往想到Zookeeper.或者Eureka.今天我们看看阿里的一款配置中心+注册中心的中间件--Nacos.有了它以后,我们的项目中的配置就可以统一从Nacos中获取了,而且Sp ...

  9. 为何不要随便用from xx import *

    新单位,新工作,远程办公,你想想有多麻烦吧. 一块块看每个模块的详细功能. 看到一个函数,返回值也是一个函数,这本来没啥难的,但是文件里只出现一次.怎么都找不到来自哪个文件,后来全项目搜才找到,原来来 ...

  10. DOM – MutationObserver

    介绍 它和 IntersectionObserver, ResizeObserver 差不多, 都是观察 element 变化的. 它可以观察元素的 attribute 增加, 移除, 修改, app ...