Code-Memo

Testing a Go app

testing package

Test files end with _test.go in the same package (package foo) or package foo_test for black-box tests.

func TestAdd(t *testing.T) {
	got := Add(2, 3)
	want := 5
	if got != want {
		t.Fatalf("Add(2,3) = %d; want %d", got, want)
	}
}

Table-driven tests

func TestAbs(t *testing.T) {
	cases := []struct {
		in, want int
	}{
		{1, 1},
		{-1, 1},
	}
	for _, tc := range cases {
		t.Run(fmt.Sprintf("%d", tc.in), func(t *testing.T) {
			if got := Abs(tc.in); got != tc.want {
				t.Fatalf("got %d", got)
			}
		})
	}
}

Helpers

func mustTempFile(t *testing.T) *os.File {
	t.Helper()
	f, err := os.CreateTemp("", "")
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { _ = os.Remove(f.Name()); _ = f.Close() })
	return f
}

Benchmarks

func BenchmarkParse(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Parse("input")
	}
}

Examples (documentation tests)

func ExampleHello() {
	fmt.Println("hello")
	// Output: hello
}

Coverage

go test -cover ./...
go test -coverprofile=cover.out ./...
go tool cover -html=cover.out

Integration tests

Build tags or separate testdata and longer tests behind -short:

if testing.Short() {
	t.Skip("skipping integration in short mode")
}

Assertions

The stdlib uses explicit if + t.Fatalf. Third-party testify is common for require / assert ergonomics.