Goc go语言下的代码覆盖率测试工具

一、关于Goc说明

在这里插入图片描述

插桩情况:

截止到Go1.15.2以前,关于覆盖率技术底层实现,
go语言采用的是插桩源码的形式,而不是待二进制执行时再去设置breakpoints。这就导致了当前go的测试覆盖率收集技术,一定是侵入式的,会修改目标程序源码。所以插过桩的二进制文件不要往线上发布

单测部分:

关于单测这块,深入go源码,我们会发现go test -cover命令会自动生成一个_testmain.go 文件。这个文件会Import各个插过桩的包,这样就可以直接读取插桩变量,从而计算测试覆盖率。实际上goc也是类似的原理(PS: 关于为何不直接用go test -c -cover 方案)

  • (精准测试受限)程序必须关闭才能收集覆盖率。如果想进一步做精准测试等方向,会很受局限。
  • (flag处理的复杂化)因为不想污染被测代码库,我们采取了自动化的方式,在编译阶段给每个服务生成类似main_test.go文件。但这种方式,其最难受的地方在于flag的处理,要知道go test命令本身会调用flag.Parse方法,所以这里需要自动化的修改源码,保证被测程序的flag定义,要先于go test调用flag.Parse之前。但是,随着程序自己使用flag姿势的复杂化,我们发现越来越难有通用方案来处理这些flag,有点难受。
  • (破坏被测程序的启动方式)受限于 go test-c命令的先天缺陷,它会给被测程序注入一些测试专属的flag,比如-test.coverprofile, -test.timeout等等。这个是最难受的,因为它会破坏被测程序的启动姿势。我们知道系统测试面对是完整被测集群,如果你需要专门维护一套测试集群来做覆盖率收集时,就会显得非常浪费。

集成测试:

集测时,被测对象通常是完整产品,涉及到多个long running的后端服务。所以goc在设计上会自动化会给每个服务注入HTTP API,同时通过服务注册中心goc server来管理所有被测服务。如此的话,就可以在运行时,通过命令goc profile实时获取整个集群的覆盖率结果,

系统测试覆盖率收集方案:

Goc如何收集go语言系统测试覆盖率。整体比较简单,大体只需要三步:

  • 首先通过 goc server命令部署一个服务注册中心,它将会作为枢纽服务跟所有的被测服务通信。
  • 使用 goc build–center=“” 命令编译被测程序。goc不会破坏被测程序的启动方式,所以你可以直接将编译出的二进制发布到集成测试环境。
  • 环境部署好之后,就可以做执行任意的系统测试。而在测试期间,可以在任何时间,通过 goc profile–center=""拿到当前被测集群的覆盖率结果。

Goc核心原理及方向:

goc在设计上,抛弃老的 go test-c-cover模式,而是直接与 go tool cover工具交互,避免因 go test命令引入的一系列弊端。goc同样没有选择自己做插桩,也是考虑go语言的兼容性,以及性能问题,毕竟 go tool cover工具,原生采用结构体来定义counter收集器,每个文件都有单独的结构体,性能相对比较可靠。goc旨在做go语言领域综合性的覆盖率工具以及精准测试系统,其还有很长的路要走:

  • 基于PR的单测/集测/系统覆盖率增量分析
  • 精准测试方向,有一定的产品化设计体验,方便研发与测试日常使用
  • 拥抱各种CICD系统
部署构建方式:
  1. 下载包到本地后推送到代码库Docker文件下;
  2. 确认压缩包中goc所在文件的路径信息;
  3. 通过docker_file.pipe,copy后解压;
# 1. copy goc包(当前包所在代码库的路径)
COPY COPY docker/xxx .
# 2. 解压goc包
RUN tar -zx {} && chmod +x {解压后路径}goc && mv goc /usr/local/bin
其他组件支持

Vscode中实施展示覆盖率动态变化
Goc Coverage

二、使用方式

安装:

# Mac/AMD64
curl -s https://api.github.com/repos/qiniu/goc/releases/latest | grep "browser_download_url.*-darwin-amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | xargs -n 1 curl -L | tar -zx && chmod +x goc && mv goc /usr/local/bin

# Linux/AMD64
curl -s https://api.github.com/repos/qiniu/goc/releases/latest | grep "browser_download_url.*-linux-amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | xargs -n 1 curl -L | tar -zx && chmod +x goc && mv goc /usr/local/bin

# Linux/386
curl -s https://api.github.com/repos/qiniu/goc/releases/latest | grep "browser_download_url.*-linux-386.tar.gz" | cut -d : -f 2,3 | tr -d \" | xargs -n 1 curl -L | tar -zx && chmod +x goc && mv goc /usr/local/bin

例子

在系统测试中收集代码覆盖率
goc 可以实时收集长时运行的 golang 服务覆盖率。收集步骤只需要下面三步:

  1. 运行 goc server 命令启动一个服务注册中心:
➜  simple-go-server git:(master) ✗ goc server
  1. 运行 goc build 命令编译目标服务,然后启动插过桩的二进制。下面以 simple-go-server 工程为例:
➜  simple-go-server git:(master) ✗ goc build .
... // omit logs
➜  simple-go-server git:(master) ✗ ./simple-go-server  
  1. 运行 goc profile 命令收集刚启动的 simple server 的代码覆盖率:
➜  simple-go-server git:(master) ✗ goc profile
mode: atomic
enricofoltran/simple-go-server/main.go:30.13,48.33 13 1
enricofoltran/simple-go-server/main.go:48.33,50.3 1 0
enricofoltran/simple-go-server/main.go:52.2,65.12 5 1
enricofoltran/simple-go-server/main.go:65.12,74.46 7 1
enricofoltran/simple-go-server/main.go:74.46,76.4 1 0
...  
  1. PS:
enricofoltran/simple-go-server/main.go:30.13,48.33 13 1
基本语义为 "文件:起始行.起始列,结束行.结束列 该基本块中的语句数量 该基本块被执行到的次数"

Goc当前进展
[x] 支持系统测试中收集代码覆盖率
[x] 支持运行时对被测服务代码覆盖率计数器清零
[x] 支持精准测试
[x] 支持基于 Pull Request 的增量代码覆盖率报告
[] 优化插桩计数器带来的性能损耗

goc源码库

  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值