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 intepreted 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

