概述

运行模式

使用testdata目录保存测试所需的辅助数据。

Go 测试以两种不同的模式运行:

第一种称为本地目录模式,发生在没有 package 参数的情况下调用go test时(例如,go testgo test -v)。在这种模式下,go test会编译在当前目录中找到的包和测试,然后运行生成的测试二进制文件。在这种模式下,缓存(下面讨论)被禁用。 package 测试完成后,go test将打印摘要行,其中显示测试状态(“ok”或“FAIL”), package 名称和经过时间。

第二种称为程序包列表模式,发生在使用显式程序 package 参数调用go test时(例如go test mathgo test ./...,甚至go test .)。在这种模式下,go test编译并测试命令行上列出的每个 package 。如果某个 package 测试通过,则go test仅打印该 package 最后的 “OK” 摘要行。如果 package 测试失败,则执行测试将打印完整的测试输出。如果使用 -bench-v 标志调用,则go test会打印完整的输出,即使通过的 package 测试也是如此,以便显示请求的基准测试结果或详细的日志记录。在所有列出的 package 的测试完成并且输出了它们的输出之后,如果任何 package 测试失败,go test将打印最终的Fail状态。

仅在 package 列表模式下,go test会缓存成功的 package 测试结果,以避免不必要的重复运行测试。当可以从缓存中恢复测试结果时,go test将重新显示先前的输出,而不是再次运行测试二进制文件。如果发生这种情况,go test在摘要行中打印(cached)以代替经过的时间。

常用标志

-bench regexp

  默认情况下,不运行任何基准测试。 要运行所有基准,请使用`-bench`。 或`-bench=`。

-cover

  启用覆盖率分析。 请注意,由于覆盖率是通过在编译之前对源代码进行注释来实现的,因此启用覆盖率的编译和测试失败可能会报告与原始源不对应的行号。

-list regexp

  不会运行任何测试,基准测试或示例。 这只会列出顶级测试。 不显示子测试或子基准。

-run regexp

  仅运行与正则表达式匹配的那些测试和示例。

-timeout d

  如果测试二进制文件的运行时间超过持续时间 d,则出现 panic。 如果 d 为 0,则禁用超时。 默认值为 10 分钟(10m)。

-v
  详细的输出:在运行所有测试时记录它们。 即使测试成功,也要打印 Log 和 Logf 调用中的所有文本。

-coverprofile cover.out

  所有测试通过后,将 coverage 配置文件写入文件。 需设置 =-cover= 。

测试覆盖率

执行结果中输入代码覆盖率:go test ./... -cover

生成代码覆盖率分析文件:go test ./... -coverprofile=coverage.out

在浏览器中浏览分析文件:go tool cover -html=coverage.out

查看每个函数的代码覆盖率:go tool cover -func=coverage.out

断言库

testify 是一个测试工具包,提供了 assert/require/mock/suit 等功能。 推荐使用。

mock/stub

stackoverflow 有讨论 dummy/stub/fake/mock 区别,总的来说:

  • dummy 只是为了满足 api 或者接口所使用的虚假值,实际并不会用到。
  • fake 是创建一个可能依赖于某些外部基础设施的交互的测试实现,比如使用内存模拟 redis 缓存的调用。
  • stub 复写方法来返回预期的硬编码值,主要基于状态的更改,比如配置参数等。
  • mock 与 Stub 非常相似,但基于交互而不是基于状态。这意味着您不期望 Mock 返回某些值,而是假设进行了特定的方法调用顺序。和 stub 的区别在于依赖对象是否和被测对象有交互,从结果来看,stub 不会使测试失败,它只是为被测对象提供依赖的对象,并不改变测试结果,而 mock 则会根据不同的交互测试要求,很可能会更改测试的结果。stub 是 state-based,关注的是输入和输出。mock 是 interaction-based,关注的是交互过程

gomock

gomock 是 Go 编程语言的模拟框架,之前有 google 维护,现在有 uber 维护。

gostub

gostub 是一个使单元测试中的存根变得容易的库。

gomonkey

推荐使用。gomonkey 在 golang 中实现 monkey patching。使用该工具需要注意:

  1. 如果启用内联,Monkey 有时无法 patch 函数。尝试在禁用内联的情况下运行测试,例如:go test -gcflags=-l。 相同的命令行参数也可用于 build。
  2. gomonkey 不是线程安全的。或者任何种类的安全。

延伸阅读