blog: add Testable Examples article

Fixes golang/go#9471

Change-Id: I19b7b5bf62d6eee76e65730de535141638cf66e4
Reviewed-on: https://go-review.googlesource.com/9666
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/content/examples.article b/content/examples.article
new file mode 100644
index 0000000..aa0dd28
--- /dev/null
+++ b/content/examples.article
@@ -0,0 +1,201 @@
+Testable Examples in Go
+7 May 2015
+Tags: godoc, testing
+
+Andrew Gerrand
+
+* Introduction
+
+Godoc [[http://golang.org/pkg/testing/#hdr-Examples][examples]] are snippets of
+Go code that are displayed as package documentation and that are verified by
+running them as tests.
+They can also be run by a user visiting the godoc web page for the package
+and clicking the associated "Run" button.
+
+Having executable documentation for a package guarantees that the information
+will not go out of date as the API changes.
+
+The standard library includes many such examples
+(see the [[http://golang.org/pkg/strings/#Contains][`strings` package]],
+for instance).
+
+This article explains how to write your own example functions.
+
+* Examples are tests
+
+Examples are compiled (and optionally executed) as part of a package's test
+suite.
+
+As with typical tests, examples are functions that reside in a package's
+`_test.go` files.
+Unlike normal test functions, though, example functions take no arguments
+and begin with the word `Example` instead of `Test`.
+
+The [[https://godoc.org/github.com/golang/example/stringutil/][`stringutil` package]]
+is part of the [[https://github.com/golang/example][Go example repository]].
+Here's an example that demonstrates its `Reverse` function:
+
+	package stringutil_test
+
+	import (
+		"fmt"
+
+		"github.com/golang/example/stringutil"
+	)
+
+	func ExampleReverse() {
+		fmt.Println(stringutil.Reverse("hello"))
+		// Output: olleh
+	}
+
+This code might live in `example_test.go` in the `stringutil` directory.
+
+Godoc will present this example alongside the `Reverse` function's documentation:
+
+.image examples/reverse.png
+
+Running the package's test suite, we can see the example function is executed
+with no further arrangement from us:
+
+	$ go test -v
+	=== RUN TestReverse
+	--- PASS: TestReverse (0.00s)
+	=== RUN: ExampleReverse
+	--- PASS: ExampleReverse (0.00s)
+	PASS
+	ok  	github.com/golang/example/stringutil	0.009s
+
+* Output comments
+
+What does it mean that the `ExampleReverse` function "passes"?
+
+As it executes the example,
+the testing framework captures data written to standard output
+and then compares the output against the example's "Output:" comment.
+The test passes if the test's output matches its output comment.
+
+To see a failing example we can change the output comment text to something
+obviously incorrect
+
+	func ExampleReverse() {
+		fmt.Println(stringutil.Reverse("hello"))
+		// Output: golly
+	}
+
+and run the tests again:
+
+	$ go test
+	--- FAIL: ExampleReverse (0.00s)
+	got:
+	olleh
+	want:
+	golly
+	FAIL
+
+If we remove the output comment entirely
+
+	func ExampleReverse() {
+		fmt.Println(stringutil.Reverse("hello"))
+	}
+
+then the example function is compiled but not executed:
+
+	$ go test -v
+	=== RUN TestReverse
+	--- PASS: TestReverse (0.00s)
+	PASS
+	ok  	github.com/golang/example/stringutil	0.009s
+
+Examples without output comments are useful for demonstrating code that cannot
+run as unit tests, such as that which accesses the network, 
+while guaranteeing the example at least compiles.
+
+
+* Example function names
+
+Godoc uses a naming convention to associate an example function with a
+package-level identifier.
+
+	func ExampleFoo()     // documents the Foo function or type
+	func ExampleBar_Qux() // documents the Qux method of type Bar
+	func Example()        // documents the package as a whole
+
+Following this convention, godoc displays the `ExampleReverse` example
+alongside the documentation for the `Reverse` function.
+
+Multiple examples can be provided for a given identifier by using a suffix
+beginning with an underscore followed by a lowercase letter.
+Each of these examples documents the `Reverse` function:
+
+	func ExampleReverse()
+	func ExampleReverse_second()
+	func ExampleReverse_third()
+
+
+* Larger examples
+
+Sometimes we need more than just a function to write a good example.
+
+For instance, to demonstrate the [[https://golang.org/pkg/sort/][`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 [[https://golang.org/src/sort/][`sort` package's source code]]
+to see this in practice.
+
+* Conclusion
+
+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!
diff --git a/content/examples/reverse.png b/content/examples/reverse.png
new file mode 100644
index 0000000..c9b5ad2
--- /dev/null
+++ b/content/examples/reverse.png
Binary files differ