Go1.20 新版覆盖率方案解读
· 阅读需 9 分钟
玩过 Go 覆盖率的同学当有所了解,Go 的覆盖率方案最初的设计目标仅是针对单测场景,导致其局限性很大。而为了适配更多的场景,行业内各种博客、插件、黑科技介绍也层出不穷。当然,过去我们也开源过 Go 系统测试覆盖率收集利器 - goc,算其中比较完善,比较系统的了。且从用户使用角度来看,goc 也确实解决了行业内很多同学的痛点。
而现在,Go 官方终于开始正式这个问题了。作者Than McIntosh
于今年 3 月份提出了新的覆盖率提案,且看当前实现进度,最快 Go1.20 我们就能体验到这个能力,非常赞。
- https://github.com/golang/go/issues/51430
- https://go.googlesource.com/proposal/+/master/design/51430-revamp-code-coverage.md
基于作者的 Proposal,我们先来看看这个提案细节。
新姿势: go build -cover
需要明确的是,本次提案不会改变原来的使用姿势go test -cover
,而是新增go build -cover
使用入口。从这一变化我们不难看出,新提案主要瞄准的是 "针对程序级的覆盖率收集" ,而旧版的实际是 "仅针对包级别的覆盖率收集" ,二者设计目标有明显的差别。
在新姿势下,使用流程大体是:
$ go build -o myapp.exe -cover ...
$ mkdir /tmp/mycovdata
$ export GOCOVERDIR=/tmp/mycovdata
$ <run test suite, resulting in multiple invocations of myapp.exe>
$ go tool covdata [command]
整体逻辑也比较清晰:
- 先编译出一个经过插桩的被测程序
- 配置好覆盖率输出的路径,然后执行被测程序。到这一步程序本身就会自动的输出覆盖率结果到上述路径了
- 通过
go tool covdata
来处理覆盖率结果
这里的子命令 covdata
是新引入的工具。而之所需要新工具,主要还是在新提案下,输出的覆盖率文件格式与原来的已有较大的差别。
新版覆盖率格式
先来看旧版的覆盖率结果:
mode: set
cov-example/p/p.go:5.26,8.12 2 1
cov-example/p/p.go:11.2,11.27 1 1
cov-example/p/p.go:8.12,10.3 1 1
cov-example/p/p.go:14.27,20.2 5 1