Go: Provide automated tested examples for your documentation!
Tags: go, testing, documentation
Published: 2021-08-13 07:02:40

## TL;DR:

You can provide example usage of your code which will be tested with `go test -v`. Imagine you have this really cool function:

```
// YourFunction will return "good output" no matter what.
func YourFunction(someInput string) string {
	return "good output"
}

```

Add a function in your package's `_test.go` file:

```
func ExampleYourFunction() {
	result := YourFunction("some input")
	fmt.Println(result)
	// Output: wrong output
}
```

Notice the `Example*` prefix of the function name. Now if you run `go test -v` it should break, because the output is wrong!

```
$ go test -v

=== RUN   ExampleYourFunction
--- FAIL: ExampleYourFunction (0.00s)
got:
good output
want:
wrong output
FAIL
exit status 1
FAIL    example        0.978s
```

Now change it to "good output":

```
func ExampleYourFunction() {
	result := YourFunction("some input")
	fmt.Println(result)
	// Output: good output
}
```

Now run it again:

```
$ go test -v       
=== RUN   ExampleYourFunction
--- PASS: ExampleYourFunction (0.00s)
PASS
ok      integers        0.366s
```

Yey!

## Detailed explanation

You can provide examples for your code which will be tested, you can see it with `go test -v`.

1. Create a new directory `integers`

```
$ mkdir integers
```

2. Init our new go module (not required)

```
$ go mod init integers
```

3. Create a new file `integers.go`
 and put this function inside which we will test (I recommend you to type it instead of copy just for the sake of exercising your muscle memory)


```
package integers

// Multiply takes two integers and returns their product
func Multiply(x, y int) int {
	return x * y
}

```


4. Examples are living along with the automated tests in the `_test` file, create a new `integers_test.go` file and type your example for the function:


```
package integers

import (
	"fmt"
)

func ExampleMultiply() {
	product := Multiply(3, 3)
	fmt.Println(product)
	// Output: 8
}

```

5. You may already noticed but the `// Output: 8` is not the result this function will return, this is exactly what we wanted: **to have something that breaks.** Let's check it ourselves:

```
$ go test -v
=== RUN   ExampleMultiply
--- FAIL: ExampleMultiply (0.00s)
got:
9
want:
8
FAIL
exit status 1
FAIL    integers        0.878s
```

We intentionally implemented it in a way to **actually see it fail**, but normally after a refactor you simply run your tests and `go test` will take care about the *examples* you provided. Now let's correct our mistake!

6. Fix the output and run your tests again:

```
func ExampleMultiply() {
	product := Multiply(3, 3)
	fmt.Println(product)
	// Output: 9
}
```

```
$ go test -v
=== RUN   ExampleMultiply
--- PASS: ExampleMultiply (0.00s)
PASS
ok      integers        0.880s
```

7. Now let's see how does this look in the documentation. Run godoc to see it [troubleshooting](#troubleshooting):


```
$ godoc -http :8000
```

Now navigate to the documentation: [http://localhost:8000/pkg/integers/](http://localhost:8000/pkg/integers/)

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uswngzyd29cq52rtga4x.png)


Amazing! Right? You have an example which is also a test, and  even if you intentionally implement API breaking changes (which we obviously try to avoid) than **you will see that you have to change your documentation.**

## I hope you enjoyed it! Here are the sources:

1. I learned this from the [Learn go with tests](https://quii.gitbook.io/learn-go-with-tests/go-fundamentals/iteration) book, I highly recommend to read it!
2. If you are interested in more detailed examples, check [The Go Blog: Testable Examples in Go](https://blog.golang.org/examples)
 

### Troubleshooting
In Go 1.14+ godoc is no longer included, you may have to install it directly:

```
$ go get golang.org/x/tools/cmd/godoc
```