go-code-review
Use when reviewing Go code or checking code against community style standards. Also use proactively before submitting a Go PR or…
Use when writing, reviewing, or improving Go test code — including table-driven tests, subtests, parallel tests, test helpers, test doubles, and assertions with cmp.Diff. Also use when a user asks to write a test for a Go function, even if they don't mention specific patterns
$ npx -y skills add cxuu/golang-skills --skill go-testing --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/go-testingContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when writing, reviewing, or improving Go test code — including table-driven tests, subtests, parallel tests, test helpers, test doubles, and assertions with cmp.Diff. Also use when a user asks to write a test for a Go function, even if they don't mention specific patterns
name: go-testing description: Use when writing, reviewing, or improving Go test code — including table-driven tests, subtests, parallel tests, test helpers, test doubles, and assertions with cmp.Diff. Also use when a user asks to write a test for a Go function, even if they don't mention specific patterns like table-driven tests or subtests. Does not cover benchmark performance testing (see go-performance). allowed-tools: Bash(bash:*)
> Compatibility: Diff examples may use `github.com/google/go-cmp`.
| Pattern | Use When | |---------|----------| | `t.Error` | Default — report failure, keep running | | `t.Fatal` | Setup failed or continuing is meaningless | | `cmp.Diff` | Comparing structs, slices, maps, protos | | Table-driven | Many cases share identical logic | | Subtests | Need filtering, parallel execution, or naming | | `t.Helper()` | Any test helper function (call as first statement) | | `t.Cleanup()` | Teardown in helpers instead of defer |
---
> **Normative**: Test failures must be diagnosable without reading the test > source.
Every failure message must include: function name, inputs, actual (got), and expected (want). Use the format `YourFunc(%v) = %v, want %v`.
// Good:
t.Errorf("Add(2, 3) = %d, want %d", got, 5)
// Bad: Missing function name and inputs
t.Errorf("got %d, want %d", got, 5)Always print got before want: `got %v, want %v` — never reversed.
---
> **Normative**: Do not use assertion libraries. Use `cmp.Diff` for complex > comparisons.
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("GetPost() mismatch (-want +got):\n%s", diff)
}For protocol buffers, add `protocmp.Transform()` as a cmp option. Always include the direction key `(-want +got)` in diff messages. Avoid comparing JSON/serialized output — compare semantically instead.
---
> **Normative**: Use `t.Error` by default to report all failures in one run. > Use `t.Fatal` only when continuing is impossible.
**Choose `t.Fatal` when:**
encode)
**Never call `t.Fatal`/`t.FailNow` from a goroutine** other than the test goroutine — use `t.Error` instead.
---
> See `assets/table-test-template.go` when scaffolding a new table-driven test and need the canonical struct, loop, and subtest layout.
> **Advisory**: Use table-driven tests when many cases share identical logic.
**Use table tests when:** all cases run the same code path with no conditional setup, mocking, or assertions. A single `shouldErr` bool is acceptable.
**Don't use table tests when:** cases need complex setup, conditional mocking, or multiple branches — write separate test functions instead.
**Key rules:**
> **Validation**: After generating or modifying tests, run `go test -run TestXxx -v` to verify the tests compile and pass. Fix any compilation errors before proceeding.
---
> **Normative**: Test helpers must call `t.Helper()` first and use `t.Cleanup()` > for teardown.
func setupTestDB(t *testing.T) *sql.DB {
t.Helper()
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatalf("Could not open database: %v", err)
}
t.Cleanup(func() { db.Close() })
return db
}---
> **Advisory**: Test error semantics, not error message strings.
// Bad: Brittle string comparison
if err.Error() != "invalid input" { ... }
// Good: Semantic check
if !errors.Is(err, ErrInvalidInput) { ... }For simple presence checks when specific semantics don't matter:
if gotErr := err != nil; gotErr != tt.wantErr {
t.Errorf("f(%v) error = %v, want error presence = %t", tt.input, err, tt.wantErr)
}---
AI Agent Skills for writing idiomatic, production-quality Go code. 20 modular skills teach AI coding assistants Go best practices derived from: Google Go Style Guide Effective Go Uber Go Style Guide Go Wiki CodeReviewComments Skills are tuned following
Use when reviewing Go code or checking code against community style standards. Also use proactively before submitting a Go PR or…
Use when writing concurrent Go code — goroutines, channels, mutexes, or thread-safety guarantees. Also use when parallelizing…
Use when working with context.Context in Go — placement in signatures, propagating cancellation and deadlines, and storing values…
Use when writing conditionals, loops, or switch statements in Go — including if with initialization, early returns, for loop…
Use when working with Go slices, maps, or arrays — choosing between new and make, using append, declaring empty slices (nil vs…
Use when declaring or initializing Go variables, constants, structs, or maps — including var vs :=, reducing scope with if-init,…