本文讲Go的几种单元测试
单元测试
Go 官方的 testing
包
要编写一个测试文件,需要创建一个名称以
_test.go
结尾的文件,该文件包含TestXxx
函数,如上所述。 将该文件放在与被测试文件相同的包中。该文件将被排除在正常的程序包之外,但在运行go test
命令时将被包含
- 运行结果
这里介绍几个常用的参数:
-bench regexp
: 执行相应的benchmarks
,例如-bench=
(基准测试)-cover
: 开启测试覆盖率-run regexp
: 只运行regexp
匹配的函数,例如-run=Array
那么就执行包含有 Array 开头的函数;-v
显示测试的详细命令
基准测试
benchmark
和普通的单元测试用例一样,都位于_test.go
文件中。
函数名以Benchmark
开头,参数是b *testing.B
。
运行用例
go test <module name>/<package name>
用来运行某个 package 内的所有测试用例。
- 运行当前
package
内的用例:go test example
或go test .
- 运行子
package
内的用例:go test example/<package name>
或go test ./<package name>
- 如果想递归测试当前目录下的所有的
package:go test ./...
或go test example/...
查看内存分配
可以看到生成 100w
个数字的随机序列,GenerateWithCap
的耗时比 Generate
少 20%
- 使用
-benchmem
参数看到内存分配的情况:
Generate
分配的内存是 GenerateWithCap
的 5 倍,设置了切片容量,内存只分配一次,而不设置切片容量,内存分配了 38
次。
模糊测试
Go模糊测试会调用
f.Add
函数和f.Fuzz
函数
f.Add
函数把指定输入作为模糊测试的种子语料库(seed corpus),fuzzing
基于种子语料库生成随机输入。f.Fuzz
函数接收一个fuzz target
函数作为入参。fuzz target
函数有多个参数,第一个参数是*testing.T
,其它参数是被模糊的类型
上面的fuzzing
测试结果是FAIL,引起FAIL的输入数据被写到了一个语料库文件里。下次运行go test
命令的时候,即使没有-fuzz
参数,这个语料库文件里的测试数据也会被用到。
可以用文本编辑器打开testdata/fuzz/FuzzReverse
目录下的文件,看看引起Fuzzing
测试失败的测试数据长什么样
发现问题,试着修改BUG
在Go语言里,字符串是只读的字节切片(In Go, a string is a read only slice of bytes
),字节切片里的每个字节不一定都是有效的UTF-8编码的字节,详情可以参考a string is a read only slice of bytes
运行模糊测试 go test -fuzz=Fuzz
,执行几秒后,使用 ctrl-C
结束测试。