go 语言 测试 示例函数

示例函数

Example开头,后面加对应的函数名,示例没有参数列表与返回值列表

func ExampleFibMap() {...}

后缀FibMap的首字母是大写,因为这个函数在源码中就是大写,必须与源码保持一致,如果写为fibMap,那么会提示 ExampleFibWithMap refers an unknown identifier,即无法与对应的函数相关联。

要注意的是,因为FibMap方法是可导出的,它的示例函数要写为ExampleFibMap,如果方法是不可导出的,那么它的示例函数要写为Example_xxx的形式,如fibWithMap方法的示例函数可以命名为Example_fibWithMap

命名约定

Go 语言通过大量的命名约定来简化工具的复杂度,规范代码的风格。对示例函数的命名有如下约定:

  • 包级别的示例函数,直接命名为 func Example() { ... }
  • 函数 F 的示例,命名为 func ExampleF() { ... }
  • 类型 T 的示例,命名为 func ExampleT() { ... }
  • 类型 T 上的 方法 M 的示例,命名为 func ExampleT_M() { ... }

如果同一个方法需要提供多个示例,可以在示例函数名称后附加一个不同的后缀来实现,但这种后缀必须以小写字母开头,大写也是可以的

func Example_suffix() { ... }
func ExampleF_suffix() { ... }
func ExampleT_suffix() { ... }
func ExampleT_M_suffix() { ... }

示例代码会放在单独的示例文件中,如example_test.go

https://github.com/golang/go/blob/master/src/bytes/example_test.go

测试示例函数

// 测试通过
go test gott/fib -run=ExampleFibMap
ok      gott/fib        0.008s

// 测试不通过
go test gott/fib -run=ExampleFibMap
--- FAIL: ExampleFibMap (0.00s)
got:
102334155
want: // 这里就是output 后面期待的值
102334156
FAIL
FAIL    gott/fib        0.012s
FAIL

有时候,输出顺序可能不确定,比如循环输出 map 的值,那么可以使用 Unordered output 开头的注释

示例函数的作用

  1. 作为文档使用

    它可以直观的展示一个函数的用法与功能。根据Example的后缀部分,godoc文档服务会把示例函数关联到函数本身,在查询在线文档的时候,可以看到函数的具体用法及示例函数

  2. 验证函数是否正确

    如果示例函数中包含// Output注释,那么在执行 go test 的时候,示例函数也会被运行,然后检查标准输出是否与注释匹配,不匹配则做为测试失败处理。如果示例函数中没有包含// Output注释,那么 go test 的时候,它不会被运行

  3. 可以在 godoc 提供的在线文档上显示,包括函数信息,示例函数

源码文件

// fib_test.go
func ExampleFibMap() {
	num := fibWithMap(40)
	fmt.Println(num)
	//Output:
	//102334155
	//hello
	fmt.Println("hello")
}

func Example_fibWithMap() {
	num := fibWithMap(40)
	fmt.Println(num)
	//Output:
	//102334155
}

可以有多个标准输出,与之对应的output也要有多个注释

func FibMap(x int) int {...}
func fibWithMap(x int) int {...}