testing Package: Examples, Fuzz, Bench

Updated

September 8, 2026

testing Package: Examples, Fuzz, Bench

Overview

Package testing is both a runner and a small toolkit: tests, benchmarks, examples, fuzz targets, temp dirs, and HTTP helpers via net/http/httptest.

Fundamentals also live in Part 06. This chapter is the stdlib surface checklist.

Test functions

func TestSum(t *testing.T) {
    t.Parallel()
    got := Sum(2, 3)
    if got != 5 {
        t.Fatalf("Sum(2,3)=%d want 5", got)
    }
}
Method Use
Error / Errorf Fail, continue
Fatal / Fatalf Fail, stop this test
Helper Mark assertion helpers
Cleanup Register teardown (LIFO)
TempDir Isolated temp directory
Setenv Env var for this test
Context Canceled when test ends (Go 1.24+)
Deadline Time left if -timeout set

Table tests

tests := []struct {
    name string
    a, b int
    want int
}{
    {"zero", 0, 0, 0},
    {"pos", 2, 3, 5},
}
for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        if got := Sum(tt.a, tt.b); got != tt.want {
            t.Fatalf("got %d want %d", got, tt.want)
        }
    })
}

Examples

func ExampleSum() {
    fmt.Println(Sum(1, 2))
    // Output:
    // 3
}

Examples run as tests and appear in pkg.go.dev docs. Unordered output:

// Unordered output:
// a
// b

Benchmarks

func BenchmarkSum(b *testing.B) {
    for b.Loop() { // Go 1.24+; or for i := 0; i < b.N; i++
        Sum(2, 3)
    }
}
go test -bench=BenchmarkSum -benchmem ./...

Fuzzing

func FuzzReverse(f *testing.F) {
    f.Add("gopher")
    f.Fuzz(func(t *testing.T, s string) {
        rev := Reverse(s)
        dbl := Reverse(rev)
        if dbl != s {
            t.Fatalf("roundtrip %q -> %q -> %q", s, rev, dbl)
        }
    })
}
go test -fuzz=FuzzReverse -fuzztime=10s

Failing inputs land under testdata/fuzz/ — commit them as regression seeds.

fstest and httptest

fsys := fstest.MapFS{"a.txt": {Data: []byte("x")}}
b, err := fs.ReadFile(fsys, "a.txt")

req := httptest.NewRequest(http.MethodGet, "/x", nil)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)

// Go 1.27+: in-memory server (synctest-safe, auto-cleanup)
ts := httptest.NewTestServer(t, handler)
resp, err := ts.Client().Get("http://example.com/x")

Commands

go test ./...
go test -v -run TestSum
go test -race ./...
go test -coverprofile=c.out && go tool cover -html=c.out
go test -bench=. -benchmem
go test -fuzz=. -fuzztime=30s

Runnable example

Save as sum.go and sum_test.go in a module:

mkdir /tmp/stdlib-test && cd /tmp/stdlib-test
go mod init example

sum.go:

package example

func Sum(a, b int) int { return a + b }

func Reverse(s string) string {
    r := []rune(s)
    for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
        r[i], r[j] = r[j], r[i]
    }
    return string(r)
}

sum_test.go:

package example

import (
    "fmt"
    "testing"
)

func TestSum(t *testing.T) {
    if Sum(2, 3) != 5 {
        t.Fatal("bad sum")
    }
}

func ExampleSum() {
    fmt.Println(Sum(1, 2))
    // Output:
    // 3
}

func FuzzReverse(f *testing.F) {
    f.Add("ab")
    f.Fuzz(func(t *testing.T, s string) {
        if Reverse(Reverse(s)) != s {
            t.Fatal("roundtrip")
        }
    })
}

func BenchmarkSum(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Sum(i, i)
    }
}
go test -v
go test -bench=BenchmarkSum -benchmem
go test -fuzz=FuzzReverse -fuzztime=3s

What to notice: - Examples are documentation that cannot drift silently. - Fuzz finds encoding edge cases ([]rune vs bytes) faster than hand-written tables. - Benchmarks need stable loops; avoid timing setup inside b.N work.

Try next: Use t.TempDir and os.WriteFile to test a function that reads a config path.