Example tests in Go
Tags: 100daystooffload, go, testing, programming
Published: 2024-03-21 19:38:45

I really like the tooling in Go when working with different kind of tests.

This time we will explore the `Example` feature in the [testing package](https://pkg.go.dev/testing#hdr-Examples) from the standard library. This is often used in the documentation of packages and can be displayed as it's done in the `fmt` package.

![Example from fmt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zguk7l7kzkupst49jyo8.png)

To show how this is working in practice we will reuse the calculator code from the [quick.Check](https://dev.to/stefanalfbo/quickcheck-in-go-4ppi) post.

```golang
package calculator

// Calculator defines a simple calculator with basic operations.
type Calculator struct{}

func (c *Calculator) Add(a, b int) int {
    return a + b
}

func (c *Calculator) Subtract(a, b int) int {
    return a - b
}

func (c *Calculator) Multiply(a, b int) int {
    return a * b
}

func isZero(n int) bool {
    return n == 0
}

func (c *Calculator) Divide(a, b int) int {
    if isZero(b) {
        panic("division by zero")
    }

    return a / b
}
```

The example tests are located in a package's `_test.go` file, and of course there is a naming convention for an example test, the function should start with the prefix `Example`.

Lets create a `calculator_test.go` file and write our first example test.

```golang
package calculator_test

import (
	calculator "example/tests"
	"fmt"
)

func ExampleCalculator_Add() {
	c := calculator.Calculator{}
	fmt.Println(c.Add(1, 2))
	// Output: 3
}

```

And by running `go test -v` we will get this output.

![go test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lvo2e1069dhyqrg3wcmm.png)

As you can see it runs the example test like a regular unit test. If we change the comment to `// Output: 4` in the example test above, we will get following result.

![failed test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1tnhxxavkxu1f3p3h6t.png)

Now the test failed, but lets move on and see if can visualize our example test. I have initialized the calculator go module like this.

```bash
go mod init example/tests
```

By running the command, `go doc`, the output will look like this.

![go doc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urttej1nk5x98g269fod.png)

No traces of the example test in that output. However if we install the `godoc` tool we will get a better result.

```sh
go install golang.org/x/tools/cmd/godoc
``` 

And then start the go documentation server.

```sh
godo -http=:6060
```

Now when we surf to, `http://localhost:6060/`, there will be a familiar page there, and somewhere in the middle of that page we can see our package.

![example test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/04siqzhfzo5q62qu2xf6.png)

Click on `tests` and go down to the documentation for our `Add` function.

![example test for add](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4c8ww76hk8egzahfzp96.png)

Voila, there it is, the example test. The `fmt` documentation also has an entire test file as an example. To make that happen you will need to fulfill this:

> The entire test file is presented as the example when it contains a single example function, at least one other function, type, variable, or constant declaration, and no test or benchmark functions.

Ok, create a new file called, `calculator_subtract_test.go` and add the following code to it.

```golang
package calculator_test

import (
	calculator "example/tests"

	"fmt"
)

func Print(result int) {
	fmt.Println(result)
}

func ExampleCalculator_Subtract() {
	c := calculator.Calculator{}
	Print(c.Subtract(2, 1))
	// Output: 1
}
```

Here we are adding at least one other function, `Print`. Refresh the documentation page and you will see the following in the example code for the `Subtract` function.

![subtraction code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pd11s1eyrp53la4r75kr.png)

There it is, an entire test file as an example. To learn more then perhaps this blog, [Testable Examples in Go](https://go.dev/blog/examples), on the [The Go Blog](https://go.dev/blog/) can be a good starting point.

Take care!