并行测试包,Go 测试的一种约定

一年前,项目中的每个测试用例都被标记为["t.Parallel" and "paralleltest"],起初对这是否值得努力持怀疑态度,因为跨 Go 包的测试已在并行进行,但这对单独运行大型包有很大帮助,测试时间减少了 30%以上。之后又将每个子测试也标记为t.Parallel,虽效果没那么大,但在单独运行有很多子测试的测试时很有帮助,且现在已实施,维持起来也不费力。

目前正在运行近 5000 个测试,Go 中大规模代码重构工具不普遍,通过一些复杂的多行正则表达式进行了大部分重构,之所以能做到是因为对保持强代码约定很执着,大多数测试用例结构相同,起初看似不必要,但后来在数小时而不是数周内重构数千个测试时得到了回报。

展示了一个有用的测试约定,用于使子测试并行安全、保持 DRY(与许多语言不同,Go 没有内置的测试设置/拆卸块设施)且保持代码可读。测试包结构简单,包含被测试对象和跨子测试可用的固定装置。有一个setup辅助函数返回测试包和上下文,上下文可用于在测试运行时确保日志输出与测试相关联,而不是与其他并行运行的测试交错。每个子测试标记为并行并调用setup获取测试包,每个测试包实例相互完全隔离,每个测试用例使用测试事务,即使测试包只包含一个字段也会放入,这是为了方便未来开发者扩充测试且保持约定。还给出了一个完整代码示例,展示了所有步骤,并提到了PartialEqual辅助函数,起初不确定,现在很认可其有效性。

阅读 16
0 条评论