golang测试踩坑
Golang 测试踩坑与心得
资源 & 文章
Golang单元测试指引:https://zhuanlan.zhihu.com/p/267341653
字节团队mockey文章:https://juejin.cn/post/7283037880086708258
字节mockey介绍:https://juejin.cn/post/7159568574699274248
字节mockey仓库:https://github.com/bytedance/mockey
mockery仓库:https://github.com/vektra/mockery
框架选择
市面上形形色色的测试框架眼花缭乱,虽然功能强大,但是选择起来也不是可以乱选的。应该先了解自己的测试场景,再选择合适的框架。
首先明确,抛开原生的go标准库测试包testing不谈,测试框架分为几类:
- Assertion 断言框架
- Mock 框架
- 等等
主流方式是:每个类别选择一个框架,再结合原生testing进行测试代码的编写。
如果要推荐的话:
- mockey + goconvey + 原生库
- mockery + testify + 原生库
原生testing包
原生支持,但什么都得自己写。
Assertion框架
testify
goconvey
Mock框架
Mock流派
Mock分为两种流派:
- 运行时打桩(Monkey Patching):在测试运行时动态地替换方法、成员函数、变量,无需 interface,无需提前生成mock。代表框架有 monkey 和字节的 mockey。
- 代码生成(mockgen):生成 interface 的 mock代码的工具,依赖注入mock,是编译时生成,是静态的。代表有 mockery 等。
这两种流派是不兼容的,意味着选择一种就要抛弃另一种。
字节mockey
字节开源的一款 monkey类mock 框架,无需生成代码,无需特地编写mock对象,拿起来就用。“不需要依赖注入,直接 mock 内存”。
通过 Mock api 实现动态地mock,缺点是无法mock interface,只能mock 具体成员函数 或 全局函数 或 变量。
另外,mockey的文档中推荐了 goconvey 作为搭配的断言框架。
monkey
没用过
mockery
应该是最流行的 mock框架,官网介绍很多大项目都在用,如kubernetes。它是生成代码式框架,并且只能mock interface,普通的struct就不好mock了。
使用 mockery 时需要先安装它的CLI工具,编写yaml配置(命令行参数也可以),再生成mock代码。mockery 提供了对 testify 的内部支持,可以搭配 testify 使用。
go test 命令
./...:递归查找该目录下所有*_test.go文件。.:仅测试当前包-v:输出详细日志-cover:输出覆盖率-coverprofile=coverage.out:输出覆盖率到coverage.out文件go tool cover -html=coverage.out:html可视化覆盖率
坑
mockey无法mock interface?
答:确实。mockey只能 mock 具体的type,也就是interface的 underlying struct。
有人提了issue,但四年了还open着。
那我的依赖如果是interface就无法mock了吗?
不是,可以通过反射找到concrete type的concrete method。官网仓库FAQ里提到了这点:How to mock interface types?
mockey如何 mock 泛型方法?
mockey.Mock 无法对泛型生效;应该使用mockey.MockGeneric。
内联优化
使用 mockey 时应该关闭golang的内联优化,对go test添加参数:
1 | |
使用 monkey patching 类的mock框架都应该关闭内联优化,防止函数运行时替换不成功。