github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/blog/content/examples.article (about) 1 Testable Examples in Go 2 7 May 2015 3 Tags: godoc, testing 4 5 Andrew Gerrand 6 7 * Introduction 8 9 Godoc [[http://golang.org/pkg/testing/#hdr-Examples][examples]] are snippets of 10 Go code that are displayed as package documentation and that are verified by 11 running them as tests. 12 They can also be run by a user visiting the godoc web page for the package 13 and clicking the associated "Run" button. 14 15 Having executable documentation for a package guarantees that the information 16 will not go out of date as the API changes. 17 18 The standard library includes many such examples 19 (see the [[http://golang.org/pkg/strings/#Contains][`strings` package]], 20 for instance). 21 22 This article explains how to write your own example functions. 23 24 * Examples are tests 25 26 Examples are compiled (and optionally executed) as part of a package's test 27 suite. 28 29 As with typical tests, examples are functions that reside in a package's 30 `_test.go` files. 31 Unlike normal test functions, though, example functions take no arguments 32 and begin with the word `Example` instead of `Test`. 33 34 The [[https://godoc.org/github.com/golang/example/stringutil/][`stringutil` package]] 35 is part of the [[https://github.com/golang/example][Go example repository]]. 36 Here's an example that demonstrates its `Reverse` function: 37 38 package stringutil_test 39 40 import ( 41 "fmt" 42 43 "github.com/golang/example/stringutil" 44 ) 45 46 func ExampleReverse() { 47 fmt.Println(stringutil.Reverse("hello")) 48 // Output: olleh 49 } 50 51 This code might live in `example_test.go` in the `stringutil` directory. 52 53 Godoc will present this example alongside the `Reverse` function's documentation: 54 55 .image examples/reverse.png 56 57 Running the package's test suite, we can see the example function is executed 58 with no further arrangement from us: 59 60 $ go test -v 61 === RUN TestReverse 62 --- PASS: TestReverse (0.00s) 63 === RUN: ExampleReverse 64 --- PASS: ExampleReverse (0.00s) 65 PASS 66 ok github.com/golang/example/stringutil 0.009s 67 68 * Output comments 69 70 What does it mean that the `ExampleReverse` function "passes"? 71 72 As it executes the example, 73 the testing framework captures data written to standard output 74 and then compares the output against the example's "Output:" comment. 75 The test passes if the test's output matches its output comment. 76 77 To see a failing example we can change the output comment text to something 78 obviously incorrect 79 80 func ExampleReverse() { 81 fmt.Println(stringutil.Reverse("hello")) 82 // Output: golly 83 } 84 85 and run the tests again: 86 87 $ go test 88 --- FAIL: ExampleReverse (0.00s) 89 got: 90 olleh 91 want: 92 golly 93 FAIL 94 95 If we remove the output comment entirely 96 97 func ExampleReverse() { 98 fmt.Println(stringutil.Reverse("hello")) 99 } 100 101 then the example function is compiled but not executed: 102 103 $ go test -v 104 === RUN TestReverse 105 --- PASS: TestReverse (0.00s) 106 PASS 107 ok github.com/golang/example/stringutil 0.009s 108 109 Examples without output comments are useful for demonstrating code that cannot 110 run as unit tests, such as that which accesses the network, 111 while guaranteeing the example at least compiles. 112 113 114 * Example function names 115 116 Godoc uses a naming convention to associate an example function with a 117 package-level identifier. 118 119 func ExampleFoo() // documents the Foo function or type 120 func ExampleBar_Qux() // documents the Qux method of type Bar 121 func Example() // documents the package as a whole 122 123 Following this convention, godoc displays the `ExampleReverse` example 124 alongside the documentation for the `Reverse` function. 125 126 Multiple examples can be provided for a given identifier by using a suffix 127 beginning with an underscore followed by a lowercase letter. 128 Each of these examples documents the `Reverse` function: 129 130 func ExampleReverse() 131 func ExampleReverse_second() 132 func ExampleReverse_third() 133 134 135 * Larger examples 136 137 Sometimes we need more than just a function to write a good example. 138 139 For instance, to demonstrate the [[https://golang.org/pkg/sort/][`sort` package]] 140 we should show an implementation of `sort.Interface`. 141 Since methods cannot be declared inside a function body, the example must 142 include some context in addition to the example function. 143 144 To achieve this we can use a "whole file example." 145 A whole file example is a file that ends in `_test.go` and contains exactly one 146 example function, no test or benchmark functions, and at least one other 147 package-level declaration. 148 When displaying such examples godoc will show the entire file. 149 150 Here is a whole file example from the `sort` package: 151 152 package sort_test 153 154 import ( 155 "fmt" 156 "sort" 157 ) 158 159 type Person struct { 160 Name string 161 Age int 162 } 163 164 func (p Person) String() string { 165 return fmt.Sprintf("%s: %d", p.Name, p.Age) 166 } 167 168 // ByAge implements sort.Interface for []Person based on 169 // the Age field. 170 type ByAge []Person 171 172 func (a ByAge) Len() int { return len(a) } 173 func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 174 func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age } 175 176 func Example() { 177 people := []Person{ 178 {"Bob", 31}, 179 {"John", 42}, 180 {"Michael", 17}, 181 {"Jenny", 26}, 182 } 183 184 fmt.Println(people) 185 sort.Sort(ByAge(people)) 186 fmt.Println(people) 187 188 // Output: 189 // [Bob: 31 John: 42 Michael: 17 Jenny: 26] 190 // [Michael: 17 Jenny: 26 Bob: 31 John: 42] 191 } 192 193 A package can contain multiple whole file examples; one example per file. 194 Take a look at the [[https://golang.org/src/sort/][`sort` package's source code]] 195 to see this in practice. 196 197 * Conclusion 198 199 Godoc examples are a great way to write and maintain code as documentation. 200 They also present editable, working, runnable examples your users can build on. 201 Use them!