天天看點

Go服務自動觸發單元測試覆寫率

一、用到的工具

  • Gitlab
  • Jenkins
  • Shell
  • go test

二、實作原理

在gitlab上配置jenkins的webhook,當有代碼變更時自動觸發jenkins建構job,job内的shell腳本負責把覆寫率報告以釘釘群通知的方法發送出去。

Go服務自動觸發單元測試覆寫率

三、Jenkins job配置

Go服務自動觸發單元測試覆寫率

點選上圖中的“進階”,出現下圖後,點選“Generate”,生成Secret token。

Go服務自動觸發單元測試覆寫率

四、Gitlab配置webhook

Go服務自動觸發單元測試覆寫率

五、Shell腳本

Go服務自動觸發單元測試覆寫率

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

#擷取上次的test.go檔案數,如果沒有則建立檔案

if test -e last_time_test_go_num.txt

last_time_test_go_num=$(cat last_time_test_go_num.txt)

echo $last_time_test_go_num

touch last_time_test_go_num.txt

#擷取上次的per,如果沒有則建立檔案

if test -e last_time_per.txt

last_time_per=$(cat last_time_per.txt)

echo $last_time_per

touch last_time_per.txt

#計算兩次.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遇到一個小坑,如下圖:

Go服務自動觸發單元測試覆寫率

原因是slave機器上的git預設賬号對此gitlab倉庫權限不足,解決方法是給git clone指令加上username和password

Go服務自動觸發單元測試覆寫率

六、Go test 指令

如步驟五中所示,用到2個go test指令,如下:

go test ./... -coverprofile=cover.out                               # 生成.out檔案

go tool cover -html=cover.out -o coverage.html        # 生成Html報告

七、釘釘群通知

釘釘機器人配置:

釘釘機器人的安全設定方式有3種,我們這裡選擇方式一“自定義關鍵詞”

Go服務自動觸發單元測試覆寫率

添加釘釘機器人:

Go服務自動觸發單元測試覆寫率

請求字段說明:

Go服務自動觸發單元測試覆寫率

注意:請求的content中(content即link的值,也就是在text或title中包含)必須包含釘釘機器人的“自定義關鍵詞”,比如我們curl請求中就包含了“單元測試”,否則會報如下圖的錯誤

Go服務自動觸發單元測試覆寫率

八、通知消息展示

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

Go服務自動觸發單元測試覆寫率

繼續閱讀