Testing Techniques
Google I/O 2014

Andrew Gerrand
adg@golang.org

* Video

This talk was presented at golang-syd in July 2014.

.link http://www.youtube.com/watch?v=ndmB0bj7eyw Watch the talk on YouTube


* The basics

* Testing Go code

Go has a built-in testing framework.

It is provided by the `testing` package and the `go` `test` command.

Here is a complete test file that tests the `strings.Index` function:

.code testing/test1/string_test.go


* Table-driven tests

Go's struct literal syntax makes it easy to write table-driven tests:

.code testing/test2/string_test.go /func TestIndex/,/^}/


* T

The `*testing.T` argument is used for error reporting:

	t.Errorf("got bar = %v, want %v", got, want)
	t.Fatalf("Frobnicate(%v) returned error: %v", arg, err)
	t.Logf("iteration %v", i)

And enabling parallel tests:

	t.Parallel()

And controlling whether a test runs at all:

	if runtime.GOARCH == "arm" {
		t.Skip("this doesn't work on ARM")
	}


* Running tests

The `go` `test` command runs tests for the specified package.
(It defaults to the package in the current directory.)

	$ go test
	PASS

	$ go test -v
	=== RUN TestIndex
	--- PASS: TestIndex (0.00 seconds)
	PASS

To run the tests for all my projects:

	$ go test github.com/nf/...

Or for the standard library:

	$ go test std


* Test coverage

The `go` tool can report test coverage statistics.

	$ go test -cover
	PASS
	coverage: 96.4% of statements
	ok  	strings	0.692s

The `go` tool can generate coverage profiles that may be interpreted by the `cover` tool.

	$ go test -coverprofile=cover.out
	$ go tool cover -func=cover.out
	strings/reader.go:    Len             66.7%
	strings/strings.go:   TrimSuffix     100.0%
	... many lines omitted ...
	strings/strings.go:   Replace        100.0%
	strings/strings.go:   EqualFold      100.0%
	total:                (statements)    96.4%

* Coverage visualization

	$ go tool cover -html=cover.out

.image testing/cover.png


* Advanced techniques

* An example program

*outyet* is a web server that announces whether or not a particular Go version has been tagged.

	go get github.com/golang/example/outyet

.image testing/go1.1.png


* Testing HTTP clients and servers

The `net/http/httptest` package provides helpers for testing code that makes or serves HTTP requests.


* httptest.Server

An `httptest.Server` listens on a system-chosen port on the local loopback interface, for use in end-to-end HTTP tests.

	type Server struct {
		URL      string // base URL of form http://ipaddr:port with no trailing slash
		Listener net.Listener

		// TLS is the optional TLS configuration, populated with a new config
		// after TLS is started. If set on an unstarted server before StartTLS
		// is called, existing fields are copied into the new config.
		TLS *tls.Config

		// Config may be changed after calling NewUnstartedServer and
		// before Start or StartTLS.
		Config *http.Server
	}

	func NewServer(handler http.Handler) *Server

	func (*Server) Close() error

* httptest.Server in action

This code sets up a temporary HTTP server that serves a simple "Hello" response.

.play testing/httpserver.go /START/,/STOP/


* httptest.ResponseRecorder

`httptest.ResponseRecorder` is an implementation of `http.ResponseWriter` that records its mutations for later inspection in tests.

	type ResponseRecorder struct {
		Code      int           // the HTTP response code from WriteHeader
		HeaderMap http.Header   // the HTTP response headers
		Body      *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to
		Flushed   bool
	}

* httptest.ResponseRecorder in action

By passing a `ResponseRecorder` into an HTTP handler we can inspect the generated response.

.play testing/httprecorder.go /START/,/STOP/


* Race Detection

A data race occurs when two goroutines access the same variable concurrently and at least one of the accesses is a write.

To help diagnose such bugs, Go includes a built-in data race detector.

Pass the `-race` flag to the go tool to enable the race detector:

	$ go test -race mypkg    // to test the package
	$ go run -race mysrc.go  // to run the source file
	$ go build -race mycmd   // to build the command
	$ go install -race mypkg // to install the package


* Testing with concurrency

When testing concurrent code, there's a temptation to use sleep;
it's easy and works most of the time.

But "most of the time" isn't always and flaky tests result.

We can use Go's concurrency primitives to make flaky sleep-driven tests reliable.


* Finding errors with static analysis: vet

The `vet` tool checks code for common programmer mistakes:

- bad printf formats,
- bad build tags,
- bad range loop variable use in closures,
- useless assignments,
- unreachable code,
- bad use of mutexes,
- and more.

Usage:

	go vet [package]


* Testing from the inside

Most tests are compiled as part of the package under test.

This means they can access unexported details, as we have already seen.


* Testing from the outside

Occasionally you want to run your tests from outside the package under test.

(Test files as `package` `foo_test` instead of `package` `foo`.)

This can break dependency cycles. For example:

- The `testing` package uses `fmt`.
- The `fmt` tests must import `testing`.
- So the `fmt` tests are in package `fmt_test` and can import both `testing` and `fmt`.


* Mocks and fakes

Go eschews mocks and fakes in favor of writing code that takes broad interfaces.

For example, if you're writing a file format parser, don't write a function like this:

	func Parse(f *os.File) error

instead, write functions that take the interface you need:

	func Parse(r io.Reader) error

(An `*os.File` implements `io.Reader`, as does `bytes.Buffer` or `strings.Reader`.)


* Subprocess tests

Sometimes you need to test the behavior of a process, not just a function.

.code testing/subprocess/subprocess.go /func Crasher/,/^}/

To test this code, we invoke the test binary itself as a subprocess:

.code testing/subprocess/subprocess_test.go /func TestCrasher/,/^}/


* More information

.link http://golang.org/pkg/testing/

.link http://golang.org/cmd/go/

.link http://golang.org

