虽然前⾯我们已经介绍了使⽤ go test 命令⾃动执⾏单元测试,但是go test命令其实还是⽐较复杂的,包括很多的参数,让我们⼀⼀介绍它们。
你可以通过下⾯三条命令学习go test相关的命令和知识。
go help test
这条命令主要介绍了go test基础的知识。⽐如go test命令格式如下:
go test [build/test flags] [packages] [build/test flags & test binary flags]可以看到我们可以设置 build/test flags 参数,可以放在包的前⾯和后⾯。
既⽀持test的参数,还⽀持build参数,⽐如 -N -l 禁⽌优化和内联。
可以看到 packages 是复数,也就意味着我们可以测试⼀组package,传⼊package列表即可,⽐如 go test bytes strings。
执⾏ go test 会会搜寻指定的package下以 _test.go 结尾的⽂件,找到其中的单元测试函数并执⾏,并且会显示单元测试结果的汇总信息:
ok archive/tar 0.011s
FAIL archive/zip 0.022s
ok compress/gzip 0.033s
...如果有失败的测试,会把错误信息细节显示出来。
Go会把每⼀个package下以 _test.go 编译成独⽴的包,然后链接成⼀个test ⼆进制⽂件运⾏。
在构建test ⼆进制⽂件时,会调⽤ go vet 进⾏检查,如果发现⽂件,会直接报告这些问题并且不会运⾏这些单元测试。go vet值检查⼦集: atomic 、 bool 、 buldtags 、 errorsas、ifaceassert 、 nilfunc 、 printf 和 stringintconv 。
go test 可以使⽤两种模式运⾏:
本地⽂件夹模式
在这种模式下, 不指定
packages参数。它只编译本地⽂件夹的代码和测试。在这种模式下,缓存是被禁⽌的,所以每次执⾏总会重新编译。
最后会显示测试的状态( ok 或者 FAIL ),包名和耗时。
⽐如
go test -v、go test -run TestAbc都是这种模式。包列表模式
在这种模式下,需要显示指定包名或者包列表。包名的形式有很多种,你可以执⾏
go help packages查看包名的格式。在这种模式下,
go test会编译和执⾏每⼀个包的代码和测试。如果package单测都通过,它仅仅只会输出 ok 信息。如果失败,会输出所有的细节。如果设置了
-bench或者-v,那就对不住了,会显示所有的输出。如果任意⼀个package没有通过单测,最后会输出⼀个
FAIL。
在包列表模式下, go test 会缓存已经成功通过单测的package测试结果,避免不必要的重复测试,它会把缓存的结果显示出来,同时加上 cached 标记。
缓存中匹配的规则是,运⾏涉及相同的test⼆进制⽂件,命令⾏上的标志完全来⾃⼀组受限制的“cachebale”测试标志,⽐如 -benchtime 、 -cpu 、 -list 、 -parallel 、 -run 、 -short 、 -timeout 、 -failfast 和 -v 。如果运⾏ go test 时有此集之外的任何测试或⾮测试标志,则不会缓存结果。若要禁⽤测试缓存,请使⽤除cacheable标志以外的任何测试标志或参数。
显式禁⽤测试缓存的地道⽅法是使⽤ -count=1 。
go clean --testcache 会清除所有cached的单元测试。
go test 除了⽀持build参数(因为它需要把测试代码编译成⼆进制可执⾏程序,你可以运⾏ go help build 查看build flag),还有它⾃有的⼀些标志。
-args
将命令⾏剩余部分参数传给test⼆进制。包列表必须在此参数之前。
-c
编译test⼆进制程序为pkg.test,只是编译,并不会运⾏它,后续你可以直接运⾏这个程序。pkg为包名。⽂件名可以通过-o参数指定。
-exec xprog运⾏⼆进制程序xprog。
-i
安装这个测试所需要的依赖库。已经废弃。
-json转换测试输出为JSON格式,适合⼯具进⾏分析。可以运⾏
go doc test2json了解细节。
-o file编译这个test⼆进制程序为指定的⽂件,并且会运⾏此程序。
编译的test⼆进制程序⽀持控制测试执⾏的test flag,这些flag在下⼀节介绍:
go help testflag
执⾏ go help testflag 可以查看 go test ⽀持的test flag。有些是和benchmark相关,有些和fuzz相关,我们会在介绍它们的章节中介绍这些参数,在本节中只介绍和单元测试相关的flag。
-count n
运⾏test、benchamrk、fuzz多少次。默认⼀次。
如果指定了-cpu,那就是在每个GOMAXPROCS上执⾏n次。
Example只会运⾏⼀次。使⽤-fuzz时-count对fuzz test不起作⽤。
-cover
允许代码覆盖率分析。
-covermode set,count,atomic
设置代码覆盖率的模式。默认模式是set, 除⾮-race启⽤。-race启⽤下模式为atomic。
set: bool: 此语句是否运⾏?
count: int: 此语句要执⾏多少次?
atomic: int: 类似count, 但是在多线程环境下正确,花费更⾼。
-coverpkg pattern1,pattern2,pattern3
只对模式匹配的包进⾏代码覆盖率分析。
-cpu 1,2,4
为每⼀个测试指定GOMAXPROCS列表。默认值是当前的GOMAXPROCS。
-failfast
第⼀个测试失败后并不启动新的单元测试。
-json
以JSOn格式输出。
-list regexp
输出test、benchmark、fuzz test、example列表。
-parallel n
允许并发执⾏设置了t.Parallel的test函数和fuzz targets。
-run regexp
只运⾏匹配的test、example、fuzz test。
For tests, the regular expression is split by unbracketed正则表达式如果有斜杠 (/) ,那么它匹配⼦测试。⽐如-run=X/Y 匹配所有X下⽆⼦测试以及X下⼦测试匹配Y的测试。
-short
告诉⻓时间允许的测试缩短它们的测试时间。
-shuffle off,on,N
随机化执⾏测试和benchmark。默认禁⽤。
-timeout d
如果⼀个测试运⾏超过d,就会panic。
如果d设置为0, timeout参数会被禁⽤。默认10分钟。
-v
开启详细输出。
-vet list
配置go test运⾏是go vet的检查项。
-coverprofile cover.out
将代码覆盖率写⼊到⼀个⽂件中。下⾯的参数是和profile相关:
-benchmem
为benchmark输出内存分配统计。
-blockprofile block.out
输出goroutine blocking profile到指定的⽂件。
-blockprofilerate n
控制goroutine blocking profile细节,调⽤runtime.SetBlockProfileRate。
-cpuprofile cpu.out
写CPU profile到⼀个指定的⽂件。
-memprofile mem.out
写allocation profile到⼀个指定的⽂件。
-memprofilerate n
允许更精准的memory allocation profile,通过设置runtime.MemProfileRate。
-mutexprofile mutex.out
写mutex contention profile 到指定的⽂件。
-mutexprofilefraction n
在n个goroutine持有竞争锁的stack trace采样。
-outputdir directory
profile输出⽂件的⽬录,默认go test运⾏的⽬录。
-trace trace.out
写execution trace 信息到指定的⽂件。每⼀个flag可以加⼀个 test. 的前缀,⽐如 -test.v ,这些参数也可以传递给编译的test⼆进制
程序。
⽐如 go test -v -args -x -v , 相应的⼆进制程序 pkg.test -test.v -x -v。
go help testfunc
在后缀为 _test.go 的程序中,啥样的函数是test、benchmark、fuzz test和example?允许 go help testfunc 可以得到答案。
test:
func TestXxx(t *testing.T) { ... }benchmark:
func BenchmarkXxx(b *testing.B) { ... }fuzz test:
func FuzzXxx(f *testing.F) { ... }example:
func ExamplePrintln() { ... }