0


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/AMD64curl-s https://api.github.com/repos/qiniu/goc/releases/latest |grep"browser_download_url.*-darwin-amd64.tar.gz"|cut-d:-f2,3|tr-d\" |xargs-n1curl-L|tar-zx&&chmod +x goc &&mv goc /usr/local/bin

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

# Linux/386curl-s https://api.github.com/repos/qiniu/goc/releases/latest |grep"browser_download_url.*-linux-386.tar.gz"|cut-d:-f2,3|tr-d\" |xargs-n1curl-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 131
enricofoltran/simple-go-server/main.go:48.33,50.3 10
enricofoltran/simple-go-server/main.go:52.2,65.12 51
enricofoltran/simple-go-server/main.go:65.12,74.46 71
enricofoltran/simple-go-server/main.go:74.46,76.4 10...  
  1. PS:
enricofoltran/simple-go-server/main.go:30.13,48.33 131
基本语义为 "文件:起始行.起始列,结束行.结束列 该基本块中的语句数量 该基本块被执行到的次数"

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

goc源码库


本文转载自: https://blog.csdn.net/weixin_45112527/article/details/139470952
版权归原作者 AI_Eleven 所有, 如有侵权,请联系我们删除。

“Goc go语言下的代码覆盖率测试工具”的评论:

还没有评论