原文: https://blog.golang.org/examplesgit
Go自动生成的文档中有时你会看到代码例子,这些例子还能够经过点击网站上的Run按钮运行。而这些例子是从测试代码中提取出来的。github
这些代码例子是具备可测性的,而带来的优势就是当API变化的时候,代码可以及时的同步。标准库中有不少库都包含代码例子,好比strings packagegolang
这篇文章将会教会你如何给一个库写例子代码。网络
例子代码都是写在库的测试用例集里面的(以_test.go
结尾的文件)。跟普通的测试函数不一样的是,例子代码的函数不接受任何参数,命令函数命名以Example
开头(普通测试函数是以Test
开头的)框架
Go的官方例子代码库里能够找到一个 stringutil库,这个库实现了Reverse
函数ide
package stringutil_test import ( "fmt" "github.com/golang/example/stringutil" ) func ExampleReverse() { fmt.Println(stringutil.Reverse("hello")) // Output: olleh }
上面这段代码应该能够在example_test.go
里面找到。这段例子代码会自动在godoc中的Reverse函数的说明下找到。函数
运行该库的测试用例,咱们能够看到相关的Example函数也跟着一块儿运行了。测试
$ go test -v === RUN TestReverse --- PASS: TestReverse (0.00s) === RUN: ExampleReverse --- PASS: ExampleReverse (0.00s) PASS ok github.com/golang/example/stringutil 0.009s
程序是如何肯定Example函数是否PASS呢?网站
当运行Example的测试用例的时候,测试框架捕获了其标准输出,而且用其跟注释中`Output: 开头的内容进行的对比,来肯定是否调用成功ui
简单的修改下注释,就可让这个测试用例FAIL了
func ExampleReverse() { fmt.Println(stringutil.Reverse("hello")) // Output: golly }
从新运行后的效果
$ go test --- FAIL: ExampleReverse (0.00s) got: olleh want: golly FAIL
若是咱们把Example里面的注释都删掉呢
func ExampleReverse() { fmt.Println(stringutil.Reverse("hello")) }
全部Example开头的函数虽然会写到文档中,可是不会做为测试程序执行了
$ go test -v === RUN TestReverse --- PASS: TestReverse (0.00s) PASS ok github.com/golang/example/stringutil 0.009s
这种状况适用于依赖外部环境,没法做为单侧用例执行的,好比依赖一个外部的网络服务。
Godoc是经过名字来将其关联到相应的函数的
func ExampleFoo() // 做为Foo函数或者类型例子 func ExampleBar_Qux() // 做为Bar类型的Qux函数例子 func Example() // 做为整个库的例子
经过这种规则,godoc将ExampleReverse
函数对应到了Reverse
这个函数
经过增长 下划线+小写字母开头的单词做为后缀,一个函数能够对应多个例子。例如
func ExampleReverse() func ExampleReverse_second() func ExampleReverse_third()
这3个函数对对应于Reverse
这个函数。
有些时候一个函数的例子已经没法说明一个函数该如何使用。
TODO 待翻译(困死了,先睡会)
For instance, to demonstrate the sort package we should show an implementation of sort.Interface. Since methods cannot be declared inside a function body, the example must include some context in addition to the example function.
To achieve this we can use a "whole file example." A whole file example is a file that ends in _test.go and contains exactly one example function, no test or benchmark functions, and at least one other package-level declaration. When displaying such examples godoc will show the entire file.
Here is a whole file example from the sort package:
package sort_test import ( "fmt" "sort" ) type Person struct { Name string Age int } func (p Person) String() string { return fmt.Sprintf("%s: %d", p.Name, p.Age) } // ByAge implements sort.Interface for []Person based on // the Age field. type ByAge []Person func (a ByAge) Len() int { return len(a) } func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age } func Example() { people := []Person{ {"Bob", 31}, {"John", 42}, {"Michael", 17}, {"Jenny", 26}, } fmt.Println(people) sort.Sort(ByAge(people)) fmt.Println(people) // Output: // [Bob: 31 John: 42 Michael: 17 Jenny: 26] // [Michael: 17 Jenny: 26 Bob: 31 John: 42] }
A package can contain multiple whole file examples; one example per file. Take a look at the sort package's source code to see this in practice.
Godoc examples are a great way to write and maintain code as documentation. They also present editable, working, runnable examples your users can build on. Use them!
By Andrew Gerrand