译文:写在Go测试代码中例子(原文:Testable Examples in Go)
2016-05-05 13:32
513 查看
原文: https://blog.golang.org/examples
这些代码例子是具有可测性的,而带来的优点就是当API变化的时候,代码能够及时的同步。标准库中有很多库都包含代码例子,比如strings package
这篇文章将会教会你如何给一个库写例子代码。
Go的官方例子代码库里可以找到一个 stringutil库,这个库实现了
上面这段代码应该可以在
运行该库的测试用例,我们可以看到相关的Example函数也跟着一起运行了。
当运行Example的测试用例的时候,测试框架捕获了其标准输出,并且用其跟注释中`Output: 开头的内容进行的对比,来确定是否调用成功
简单的修改下注释,就可以让这个测试用例FAIL了
重新运行后的效果
如果我们把Example里面的注释都删掉呢
所有Example开头的函数虽然会写到文档中,但是不会作为测试程序执行了
这种情况适用于依赖外部环境,无法作为单侧用例执行的,比如依赖一个外部的网络服务。
通过这种规则,godoc将
通过增加 下划线+小写字母开头的单词作为后缀,一个函数可以对应多个例子。例如
这3个函数对对应于
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:
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.
By Andrew Gerrand
Organizing Go code
Godoc: documenting Go code
简介
Go自动生成的文档中有时你会看到代码例子,这些例子还可以通过点击网站上的Run按钮运行。而这些例子是从测试代码中提取出来的。这些代码例子是具有可测性的,而带来的优点就是当API变化的时候,代码能够及时的同步。标准库中有很多库都包含代码例子,比如strings package
这篇文章将会教会你如何给一个库写例子代码。
例子代码
例子代码都是写在库的测试用例集里面的(以_test.go结尾的文件)。跟普通的测试函数不同的是,例子代码的函数不接受任何参数,命令函数命名以
Example开头(普通测试函数是以
Test开头的)
Go的官方例子代码库里可以找到一个 stringutil库,这个库实现了
Reverse函数
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: 开头的内容进行的对比,来确定是否调用成功
简单的修改下注释,就可以让这个测试用例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
相关文章
The cover storyOrganizing Go code
Godoc: documenting Go code
相关文章推荐
- 使用命令修改注册表键值及权限
- centos 手动安装网卡驱动
- Fedora Linux 7 Test 4 发布 下载地址
- SQLSERVER 中GO的作用详解
- 自定义ubb代码,preg_replace()函数的一些代码
- php 正则表达式学习笔记
- 检测八位数字是否为有效日期的正则
- 向大家推荐一个收集整理正则表达式的网站
- 注意 JavaScript 中 RegExp 对象的 test 方法
- 在Go语言程序中使用gojson来解析JSON格式文件
- 举例详解Go语言中os库的常用函数用法
- Go语言中函数的参数传递与调用的基本方法
- 深入解析Go语言的io.ioutil标准库使用
- GO语言的IO方法实例小结
- JS正则表达式详解[收藏]
- PHP 正则 email语句详解
- 经典JavaScript正则表达式实战(附pdf)
- 巧解 JavaScript 中的嵌套替换(强大正则)
- 正则表达式regular expression详述(二)
- 解决preg_match匹配过多字符长度的限制的思路分析