定义:Test coverage(测试覆盖度)用于衡量一个包中的代码被测试用例覆盖的程度。
如果运行所有的测试用例能够触发包中80%的代码运行,我们就认为测试覆盖度为80%。
通常情况下,要计算测试覆盖率,需要对执行文件进行二进制拦截,比如gcov工具:通过在每个逻辑分支之后添加一个断点,来标记这个分支是否被执行到。这种基于二进制拦截的方法移植性不够好,需要针对不同CPU架构来实现。
go test -cover
package size
func Size(a int) string {
switch {
case a < 0:
return "negative"
case a == 0:
return "zero"
case a < 10:
return "small"
case a < 100:
return "big"
case a < 1000:
return "huge"
}
return "enormous"
}
重写后:
func Size(a int) string {
GoCover.Count[0] = 1
switch {
case a < 0:
GoCover.Count[2] = 1
return "negative"
case a == 0:
GoCover.Count[3] = 1
return "zero"
case a < 10:
GoCover.Count[4] = 1
return "small"
case a < 100:
GoCover.Count[5] = 1
return "big"
case a < 1000:
GoCover.Count[6] = 1
return "huge"
}
GoCover.Count[1] = 1
return "enormous"
}
GoCover.Count[]
go test -covergo test -coverprofile=cover.out
go tool cover -html=cover.out
热力图
go test -covermode=set|count|atomic-covermode
- set: 默认模式,统计是否执行
- count: 计数
- atomic: count的并发安全版本,仅当需要精确统计时使用
fmt
$ go test -covermode=count -coverprofile=count.out fmt
ok fmt 1.320s coverage: 95.1% of statements
将鼠标悬浮在代码块上可以看到具体执行的数据。
go tool cover -func=count.out
$ go tool cover -func=count.out
fmt/format.go: init 100.0%
fmt/format.go: clearflags 100.0%
fmt/format.go: init 100.0%
fmt/format.go: computePadding 84.6%
fmt/format.go: writePadding 100.0%
fmt/format.go: pad 100.0%
...
fmt/scan.go: advance 96.2%
fmt/scan.go: doScanf 96.8%
total: (statements) 91.7%
也许从这些测试中可以得到关于性能优化的提示。