zoukankan      html  css  js  c++  java
  • 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%% " $(($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 $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) | 统计----------- | 本次------ | 上次------ | 新增 | | :--- | :--- | :--- | :--- | | .go | '"$this_time_go_num"' | '"$last_time_go_num"' | '"$go_num_diff"' | | test.go | '"$this_time_test_go_num"' | '"$last_time_test_go_num"' | '"$test_go_num_diff"' | | test.go/.go | '"$this_time_per"' | '"$last_time_per"' | '"$per_diff"' | ### *_test.go覆盖率(平均值) | 本次------ | 上次------ | 差值 | | :--- | :--- | :--- | | '"$this_time"' | '"$last_time"'| '"$change"' | #### 本次&上次覆盖率HTML报告(点击打开) '"$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请求中就包含了“单元测试”,否则会报如下图的错误

    八、通知消息展示

    钉钉群接收到的通知消息:

  • 相关阅读:
    zoj 2913 Bus Pass
    poj 2478 Farey Sequence
    zoj 1649 Rescue
    秒懂JavaScript HTML DOM 元素 (节点)
    看了就会的JS(JavaScript)addEventListener()
    秒懂javascript的原型(prototype)对象、原型链的前世今生
    构造函数用途及优缺点
    一文读懂 js(JavaScript)中call() 和 apply() 的用法
    js (JavaScript)函数声明的几种形式及用法
    JavaScript 代码规范
  • 原文地址:https://www.cnblogs.com/ailiailan/p/13222036.html
Copyright © 2011-2022 走看看