go-testinglisted
Install: claude install-skill Markuysa/agent-skills
# Go testing
The standard library is enough for almost everything. Reach for a framework only
when it removes real work, not out of habit — a Go test suite that reads like
plain Go is the goal.
## Table-driven tests
The default shape for anything with more than one case:
```go
func TestParseDuration(t *testing.T) {
tests := map[string]struct {
input string
want time.Duration
wantErr error
}{
"seconds": {input: "30s", want: 30 * time.Second},
"empty is error": {input: "", wantErr: ErrEmptyInput},
"negative": {input: "-5s", want: -5 * time.Second},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
t.Parallel()
got, err := ParseDuration(tc.input)
if !errors.Is(err, tc.wantErr) {
t.Fatalf("error: got %v, want %v", err, tc.wantErr)
}
if got != tc.want {
t.Errorf("got %v, want %v", got, tc.want)
}
})
}
}
```
- **A map keyed by case name** reads better than a slice with a `name` field, and
its random iteration order surfaces accidental inter-case coupling for free.
- **Case names become the failure message** — `TestParseDuration/empty_is_error`
tells you what broke without opening the file. Name the behaviour, not the input.
- **`t.Fatalf` when continuing is meaningless**, `t.Errorf` when you want the rest
of the assertions too. `Fatalf` from a non-test g