Part 5 · 1 chapters · ~8 min
Tooling and Testing
go test with table-driven tests and subtests, testify and when not to need it, httptest for handlers, benchmarks and benchstat, native fuzzing, go vet, staticcheck and golangci-lint, integration tests with testcontainers-go, govulncheck, and dependency management with go mod.
10
Built-in tools
code
func TestFee(t *testing.T) {
cases := []struct{ name string; amount, want int64; wantErr bool }{
{"minimum applies", 100_000, 1_000, false},
{"half percent", 5_000_000, 25_000, false},
{"zero is invalid", 0, 0, true},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got, err := fee(c.amount)
if (err != nil) != c.wantErr { t.Fatalf("err = %v", err) }
if got != c.want { t.Fatalf("got %d, want %d", got, c.want) }
})
}
}
// handlers: httptest.NewRecorder() + router.ServeHTTP(rec, req), no network neededTOOLING THAT SHIPS WITH GO
most of what other ecosystems install, built in
swipe the figure sideways, or tap expand for full screen
1/6
tests
Tests live beside code in _test.go files. Table-driven tests list cases as data and loop over them with t.Run for named subtests.
table-driven, t.Run subtestsgo test ./... runs them all