Go 单元测试(二)

129 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

关于Go的单元测试核心流程在 juejin.cn/post/710316… 已经有了分享,今天主要来说一下Go单元测试常用到的测试参数

关于Go的单元测试大致可以分为两部分,一部分是控制”编译“的一部分是控制”执行的“

控制编译类参数

-args

可以通过-args参数在测试用例运行的时候传入一些自定义参数,-args 参数后面直接添加我们要传的参数即可,通过flags.Parse()获取传入的参数,方法的返回值是一个[]string类型的数组

func TestArgs(t *testing.T) {
	if flag.Parsed() {
		flag.Parse()
	}
	fmt.Printf("flag.Args: %v\n", flag.Args())
}

以传入参数 123 为例

go test -run TestArgs -args 123
pre work
flag.Args: [123]
PASS
end work
ok      gotest  0.569s

-json

通过这个参数,可以将我们的测试结果转换成json信息,以方便自动化测试解析使用。

示例如下:

go test -run TestArgs  -json         

{"Time":"2022-05-31T21:44:52.552495+08:00","Action":"output","Package":"gotest","Output":"pre work\n"}
{"Time":"2022-05-31T21:44:52.552985+08:00","Action":"run","Package":"gotest","Test":"TestArgs"}
{"Time":"2022-05-31T21:44:52.552992+08:00","Action":"output","Package":"gotest","Test":"TestArgs","Output":"=== RUN   TestArgs\n"}
{"Time":"2022-05-31T21:44:52.552996+08:00","Action":"output","Package":"gotest","Test":"TestArgs","Output":"flag.Args: []\n"}
{"Time":"2022-05-31T21:44:52.553029+08:00","Action":"output","Package":"gotest","Test":"TestArgs","Output":"--- PASS: TestArgs (0.00s)\n"}
{"Time":"2022-05-31T21:44:52.553036+08:00","Action":"pass","Package":"gotest","Test":"TestArgs","Elapsed":0}
{"Time":"2022-05-31T21:44:52.553059+08:00","Action":"output","Package":"gotest","Output":"PASS\n"}
{"Time":"2022-05-31T21:44:52.553062+08:00","Action":"output","Package":"gotest","Output":"end work\n"}
{"Time":"2022-05-31T21:44:52.553088+08:00","Action":"output","Package":"gotest","Output":"ok  \tgotest\t0.096s\n"}
{"Time":"2022-05-31T21:44:52.553094+08:00","Action":"pass","Package":"gotest","Elapsed":0.096}

-o

-o 参数指定生成的二进制可执行程序,并执行测试,测试结束不会删除该程序。 没有此参数时,go test生成的二进制可执行程序存放到临时目录,执行结束便删除。

示例如下 -o 后面是生成的可执行程序的名称

go test -run TestArgs  -o TestArgsBin

控制执行类参数

-bench <regexp>

go test默认不执行性能测试,使用-bench参数才可以运行,而且只运行性能测试函数。

其中正则表达式用于筛选所要执行的性能测试。如果要执行所有的性能测试,使用参数-bench .-bench=.

此处的正则表达式不是严格意义上的正则,而是种包含关系。

var size = 10000

func BenchmarkMakeSliceWithoutAlloc(b *testing.B) {
	for i := 0; i < b.N; i++ {
		MakeSliceWithoutAlloc(size)
	}
}

func BenchmarkMakeSliceWithPreAlloc(b *testing.B) {
	for i := 0; i < b.N; i++ {
		MakeSliceWithoutAlloc(size)
	}
}

上面示例中有两个压测方法,我们只想对BenchmarkMakeSliceWithPreAlloc方法进行压测,我们可以通过使用这个参数进行控制,

示例如下:

go test -bench=WithPreAlloc

goos: darwin
goarch: amd64
pkg: gotest
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMakeSliceWithPreAlloc-12          29397             39867 ns/op
PASS
end work
ok      gotest  4.893s

-benchtime  time

指定每个性能测试的时间,性能测试默认是执行 1s,可以通过这个参数指定性能测试的时长

例如上面的压测示例指定压测时间为3秒

go test -bench=WithPreAlloc -benchtime 3s

-benchmem

默认情况下,性能测试结果只打印运行次数、每个操作耗时。使用-benchmem则可以打印每个操作分配的字节数、每个操作分配的对象数。

go test -bench=WithPreAlloc -benchmem   

goos: darwin
goarch: amd64
pkg: gotest
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMakeSliceWithPreAlloc-12          28000             39902 ns/op          357626 B/op         19 allocs/op
PASS
ok      gotest  5.086s

-cpu <nums>

-cpu 参数提供一个CPU个数的列表,提供此参数后,那么测试将按照这个列表指定的CPU数设置GOMAXPROCS并分别测试。

比如“-cpu 1,2”,那么每个测试将执行两次,一次是用1个CPU执行,一次是用2个CPU执行。

示例如下:

go test -bench=WithPreAlloc -cpu 1,2     
goos: darwin
goarch: amd64
pkg: gotest
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMakeSliceWithPreAlloc             30170             39919 ns/op
BenchmarkMakeSliceWithPreAlloc-2           29274             34270 ns/op
PASS
ok      gotest  10.890s

-count <n>

通过这个参数可以指定每个测试用例的执行次数

比如上面的性能测试用例执行2次

go test -bench=WithPreAlloc -count 2   

goos: darwin
goarch: amd64
pkg: gotest
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMakeSliceWithPreAlloc-12          28395             40362 ns/op
BenchmarkMakeSliceWithPreAlloc-12          28797             43152 ns/op
PASS
ok      gotest  9.350s

-failfast

默认情况下,go test将会执行所有匹配到的测试,并最后打印测试结果,无论成功或失败。 -failfast指定如果有测试出现失败,则立即停止测试。这在有大量的测试需要执行时,能够更快的发现问题。

-list <regexp>

-list 只是列出匹配成功的测试函数,并不真正执行。而且,不会列出子函数。

比如列出包含PreAlloc的压测函数

go test -list PreAlloc              
BenchmarkMakeSliceWithPreAlloc
ok      gotest  0.261s

-parallel <n>

指定测试的最大并发数,当测试使用t.Parallel()方法将测试转为并发时,将受到最大并发数的限制,默认情况下最多有GOMAXPROCS个测试并发,其他的测试只能阻塞等待。

-run regexp

根据正则表达式执行单元测试和示例测试。正则匹配规则与-bench 类似。

-timeout d

这个参数很明显是用于控制测试的执行最大时间的,如果超过这个时间,那么正在执行的测试用例会立即退出。 设置超时可以按秒、按分和按时:

  • 按秒设置:-timeout xs或-timeout=xs
  • 按分设置:-timeout xm或-timeout=xm
  • 按时设置:-timeout xh或-timeout=xh

-v

默认情况下,测试结果只打印简单的测试结果,-v 参数可以打印详细的日志。

性能测试下,总是打印日志,因为日志有时会影响性能结果。