Golang 单元测试 - 其他小技
单元测试有很多技巧和科技,我都会慢慢汇总在这里
打桩测试
当我们在编写单元测试的时候,有时我们非常想 mock 掉其中一个方法,但是这个方法又没有接口去定义和实现(无法用 github.com/golang/mock
来实现),这时就可以尝试看看我们的打桩黑科技。
代码
这里我们使用 github.com/agiledragon/gomonkey 来实现。
实际中,经常在代码中会遇到一些随机值的情况,比如验证码。为了方便测试,我们会想要 mock 掉随机值方法,让每次产生的值固定方便后续的测试。
1 | package main |
其中 rand.Number()
是我们在另一个包中实现的方法。我们使用 gomonkey.ApplyFunc
相当于直接替换了原有方法的实现,强制返回了 mock 的数据 666。
注意事项
- 使用
gomonkey
时,注意一定要使用-gcflags=all=-l
来禁止内联优化,否则容易导致打桩不生效。如:go test -gcflags=all=-l -v
- 在 Mac 的 M1 下打桩不生效,可以使用环境变量
GOARCH=amd64
来进行测试,只不过这样就无法进行断点调试。https://github.com/agiledragon/gomonkey/issues/77 - 毕竟是黑科技,实际使用环境对于测试还是有影响的。
压测
这里的压测通常不是对接口的压测,而是对于某些方法的压测。Golang 提供 非常好用的 b *testing.B
来专门进行压测。
代码
非常容易上手,让我们直接来看代码
1 | var numbers = []int{ |
使用
使用 -bench=.
即可
1 | ➜ go test -bench=. b_test.go |
可以看到次数和耗时,这样的数据经常会被贴在开源项目README的性能比较板块中。
测试覆盖率
单元测试当然少不了覆盖率咯,看着高高的覆盖率才有成就感对不对?
我们可以使用 -cover
参数来统计单元测试的代码覆盖率
1 | ➜ go test -cover . |
还可以生成 profile 然后通过可视化网页查看分析
1 | ➜ go test ./... -coverprofile=cover.out |
当然,如果你和我一样使用 goland 进行开发,可以直接在界面上点击单元测试,就可以快速进行覆盖率测试,并且展示也很方便,很快能看到有哪些代码没有被测试覆盖。
表格驱动测试
TDT 的提出也算是给单元测试提供了一条不错的思路。主要的形式就是将测试的数据做成类似表格,然后测试的时候遍历所有的数据来进行测试,测试代码不动,只需要增加测试数据就可以了。go 很多官方库用了这样的写法来做测试。
1 | package main |
我们可以通过 github.com/cweill/gotests 来帮助我们快速生成想要的表格驱动测试代码