0%

Go 单元测试完全指南(三)- Example 测试

什么是 Example 测试

Example 测试是 Go 语言中的一种特殊测试,它用于展示函数或方法的使用方式。Example 测试的代码位于 _test.go 文件中,以 Example 开头,后面跟着函数名。

其实,Example 测试是 godoc 工具的一部分,它会读取代码中的 Example 测试,并将其展示在文档中。这样,用户就可以直接在文档中看到函数或方法的使用方式。

可以说,Example 测试是一种文档测试,它不仅可以测试代码,还可以帮助用户更好地理解代码。

一个简单的 Example 测试

1
2
3
4
// hello.go
func Hello() {
fmt.Println("Hello, World!")
}
1
2
3
4
5
// hello_test.go
func ExampleHello() {
Hello()
// Output: Hello, World!
}

我们执行 go test 命令就可以运行 Example 测试:

1
go test -v

如果我们的 Example 测试通过,那么输出结果会是:

1
2
3
4
=== RUN   ExampleHello
--- PASS: ExampleHello (0.00s)
PASS
ok go-test 0.004s

说明:

  1. ExampleHello 是我们的 Example 测试函数名。(注意:Hello 是规范的一部分,实际上是我们的函数名)
  2. Example 测试的格式是在代码后面加上 // Output: 注释,后面跟着期望的输出结果。如果实际输出结果和期望的输出结果一致,那么 Example 测试就通过了。
  3. Example 测试的目的是展示函数或方法的使用方式,而不只是测试。

Example 跟文档的关系

我们写的所有的 Example 测试都会被 godoc 工具读取,然后展示在文档中。这样,用户就可以直接在文档中看到函数或方法的使用方式。

我们可以通过下面的命令预览文档:

1
godoc -http=:8080

注意,如果找不到 godoc 命令,通过下面的命令安装:

1
go install golang.org/x/tools/cmd/godoc@latest

安装完成后,再将 $GOPATH/bin 目录添加到环境变量中。

示例

假设我的目录结构如下:

1
2
3
4
// go.mod
module mytest

go 1.22
1
2
3
4
5
6
7
8
9
// x/hello.go
package x

import "fmt"

// Hello prints "Hello, World!" to the console.
func Hello() {
fmt.Println("Hello, World!")
}
1
2
3
4
5
6
7
// x/hello_test.go
package x

func ExampleHello() {
Hello()
// Output: Hello, World!
}

在运行了 godoc -http=:8080 命令后,我们可以在浏览器中输入 http://localhost:8080/pkg/mytest/x/ 来查看文档:

我们可以看到 Hello 的文档以及其使用示例。

Example 测试既是测试,又是文档。

Example 测试的命名规范

  1. Example 测试的函数名必须以 Example 开头。
  2. 遵循以下的命名规范,可以让我们的 Example 在 godoc 中展示在不同的位置。
命名规范 位置
Example 在包的概述中列出
ExampleXxx 在 Xxx 函数/结构体/接口 中列出
ExampleXxx_Yyy Xxx 结构体的 Yyy 方法
ExampleXxx_Yyy_one 当你想给 Xxx 结构体的 Yyy 方法写多个示例的时候。当需要写多个示例的时候,前面几个也可以加 _one 这样的后缀

也就是说,不同的命名规范意味着是写给不同对象的示例。

无序输出的 Example 测试

如果我们的函数或方法的输出是无序的,那么我们可以使用 // Unordered 注释来标记。

1
2
3
4
5
6
7
8
9
10
func ExamplePerm() {
for _, value := range rand.Perm(5) {
fmt.Println(value)
}
// Unordered output: 4
// 2
// 1
// 3
// 0
}