Go 学习笔记(十一)- 测试

测试能保证程序的行为或结果是我们预期的,而自动化测试更是能让我们快速迭代。
Go 自带了测试工具,以及一套简单的测试规范。

go test

go test 命令是一个按照一定的约定和组织的测试代码的驱动程序。
在包目录内所有以 _test.go 后缀的源文件并不是 go build 构建包的一部分,而是 go test 测试的一部分。

有三种类型的函数:测试函数、基准测试函数、示例函数。

  • 一个测试函数是以Test为函数名前缀的函数,用于测试程序的一些逻辑行为是否正确;go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。
  • 基准测试函数是以Benchmark为函数名前缀的函数,它们用于衡量一些函数的性能;go test命令会多次运行基准函数以计算一个平均的执行时间。
  • 示例函数是以Example为函数名前缀的函数,提供一个由编译器保证正确性的示例文档。

测试函数

测试函数规范如下:

1
2
3
4
5
6
func TestName(t *testing.T) {
// 测试代码
if !测试函数("参数") {
t.Error(`测试函数("参数") = false`)
}
}

然后在当前目前下运行 go test 即可执行测试。
也可以通过 go test -v 显示具体信息包括函数名,运行时间。

-run="测试函数名的正则" 可以指定只运行指定的测试函数,在修复bug的情况下特别有用。

测试覆盖率

由测试驱动触发运行到的被测试函数的代码数目称为测试的覆盖率。

通过 -coverprofile=c.out 输出测试覆盖率文件,然后通过 go tool cover -html=c.out 生成 html 页面。
页面中绿色的代码块被测试覆盖到了,红色的则表示没有被覆盖到。

基准测试

基准测试是测量一个程序在固定工作负载下的性能。

1
2
3
4
5
func BenchmarkIsPalindrome(b *testing.B) {
for i := 0; i < b.N; i++ {
IsPalindrome("A man, a plan, a canal: Panama")
}
}

基准测试,默认不启动,我们需要添加 -bench 参数来启动基准测试。
该参数是一个正则表达式,我们通过 “.” 来匹配所有基准测试用例。
-benchmem 标志,可以显示内存的分配数据统计。

通过基准测试和普通测试,我们可以放心的修改代码让他更快更健壮。

剖析

在测试环境下只需要一个标志参数就可以生成各种分析文件。当一次使用多个标志参数时需要当心,因为分析操作本身也可能会影像程序的运行。

1
2
3
$ go test -cpuprofile=cpu.out
$ go test -blockprofile=block.out
$ go test -memprofile=mem.out

然后通过 go tool pprof 对结果进行分析。

在生成CPU分析文件的时候,可以采用 -run=NONE 禁止普通测试,而只执行基准测试。

示例函数

示例函数有三个用处。

  1. 最主要的一个是作为文档。
  2. 第二个用处是在go test执行测试的时候也运行示例函数测试。
  3. 第三个目的提供一个真实的演练场。

小结

本章是 go 的单元测试章节,提供了单元测试,基准测试和实例测试。