Go Tutorial · Standard Library · Lesson 29 of 30

Go Testing

Write table-driven tests with the testing package and go test.

Tests live next to code

Put tests in files ending in _test.go, in functions named TestXxx(t *testing.T). Run them with go test ./...:

// mathx/mathx.go
package mathx

func Abs(n int) int {
	if n < 0 {
		return -n
	}
	return n
}
// mathx/mathx_test.go
package mathx

import "testing"

func TestAbs(t *testing.T) {
	tests := []struct {
		name string
		in   int
		want int
	}{
		{"positive", 5, 5},
		{"negative", -3, 3},
		{"zero", 0, 0},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Abs(tt.in); got != tt.want {
				t.Errorf("Abs(%d) = %d, want %d", tt.in, got, tt.want)
			}
		})
	}
}
go test ./...          # all packages
go test -run TestAbs -v ./mathx
go test -race -cover ./...

This table-driven style is the idiomatic way to test Go code. Benchmarks use func BenchmarkXxx(b *testing.B).

The table-driven idea, in a plain program
package main

import "fmt"

func abs(n int) int {
	if n < 0 {
		return -n
	}
	return n
}

func main() {
	tests := []struct {
		in, want int
	}{{5, 5}, {-3, 3}, {0, 0}}
	for _, tt := range tests {
		got := abs(tt.in)
		status := "PASS"
		if got != tt.want {
			status = "FAIL"
		}
		fmt.Printf("%s abs(%d) = %d\n", status, tt.in, got)
	}
}

Output

PASS abs(5) = 5
PASS abs(-3) = 3
PASS abs(0) = 0

Run this on your computer — see “Get Started” for setup.

Test yourself

What must Go test file names end with?

  1. .test.go
  2. _test.go
  3. _spec.go
  4. Test.go
Show answer

Answer: _test.go