测试与性能调优
传统测试 vs. 表格驱动测试
Golang 采用“表格驱动测试”的做法。
传统测试
- 测试数据和测试逻辑混在一起;
- 出错信息不明确;
- 一旦一个数据出错测试全部结束;
表格驱动测试
- 分离的测试数据和测试逻辑;
- 明确的出错信息;
- 可能部分失败;
- Go 语言的语法使得我们更容易实践表格驱动测试(Java / C++ 很难实现表格驱动测试,原因是语法上支持度较差);
执行测试
在 Golang 当中,将测试的代码命名为 […]_test.go,将其与被测的代码放在一起:
以测试给定的三个整型变量是否可以构成三角形的三条边为例,triangle_test.go 应该以如下方式进行编写,从而完成表格驱动测试:
package main // 与 basic.go 的 package 相同, 都是 mainimport "testing"func TestTriangle(t *testing.T) {tests := []struct{ a, b, c int }{{3, 4, 5},{5, 12, 13},{8, 15, 17},{12, 35, 0}, // 故意引入一个错误实例{30000, 40000, 50000},}for _, tt := range tests {if actual := calcTriangle(tt.a, tt.b); actual != tt.c {t.Errorf("calcTriangle(%d, %d) = %d, want %d", tt.a, tt.b, actual, tt.c)}}
}
执行测试:
Goland 非常友好,当测试没有执行通过时,会标红:
修改测试用例,使测试通过:
如果想要在命令行中进行测试,那么直接进入到要测试的目录下,这个目录下应该包含想要测试的文件以及测试它的文件,直接使用go test .
即可完成测试。
使用测试进行代码覆盖率检察以及性能测试
可以直接在 IDE 中右键点击 test 函数,执行“使用覆盖率运行…”:
以此可以得到代码的覆盖率。
同时,可以编写用于性能测试的函数:
func BenchmarkSubstr(b *testing.B) {// 性能测试s := "TestForNonRepeatingSubstr"ans := 11actual := lengthOfNonRepeatingSubStr(s)for i := 0; i < b.N; i++ { // b.N 是 内置的用于性能测试的量if actual != ans {b.Errorf("got %d for input %s; "+"expected %d",actual, s, ans)}}
}
使用 pprof 进行性能调优
需要注意的是,刚才进行的性能调优使用的测试数据过短,可以使用以下的方式对上述性能测试函数进行改写,得到:
func BenchmarkSubstr(b *testing.B) {// 性能测试s := "TestForNonRepeatingSubstr"for i := 0; i < 13; i++ {s = s + s // 扩展测试数据}ans := 11b.Logf("len(s)=%d", len(s))b.ResetTimer() // 重置时钟, 只计算下面测试需要用的时间, 不包括扩展数据的时间for i := 0; i < b.N; i++ {actual := lengthOfNonRepeatingSubStr(s)if actual != ans {b.Errorf("got %d for input %s; "+"expected %d",actual, s, ans)}}
}
可以在命令行执行上述操作,首先在 terminal 中进入到当前路径下。
之后使用命令 go test -bench .
,在命令行中完成与 IDE 相同的测试操作。
可以进一步使用go test -bench . -cpuprofile cpu.out
来将测试的结果输入到文件当中,并使用go tool pprof cpu.out
来查看文件:
注意到,输入命令后可以在命令行进行交互,输入 web,可以在 html 输出一个可视化的结果:
这里遇到了一个坑,在第一次输入 web 的时候,会报错,提示failed to execute dot. Is Graphviz installed? Error: exec: "dot": executable file not found in %PATH%
,在查找资料后发现,需要安装 Graphviz 库,并导入到环境变量,具体做法参考了https://blog.csdn.net/June_hjx/article/details/105520532。需要注意的两个点是:
- 即使在 .exe 安装包选择了导入到环境变量,也要去检查一下环境变量;
- 安装并导入环境变量之后,应该重启 IDE。
在可视化结果当中,方框越大、线越粗,代表所花费的时间越多(联想到可以通过可视化工具来检查哪部分代码还需要优化)。