Install
$ agentstack add skill-cxuu-golang-skills-go-testing ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Go Testing
> Compatibility: Diff examples may use github.com/google/go-cmp.
Resource Routing
scripts/gen-table-test.sh- Run when generating a table-driven test scaffold.assets/table-test-template.go- Use as a copyable table-test starting point.references/TABLE-DRIVEN-TESTS.md- Read when choosing table tests, subtests, or parallel test patterns.references/TEST-HELPERS.md- Read when writing helpers, fixtures, cleanup, or test doubles.references/TEST-ORGANIZATION.md- Read when structuring packages, black-box tests, or larger test suites.references/VALIDATION-APIS.md- Read when choosingt.Error,t.Fatal,cmp.Diff, or assertion style.references/INTEGRATION.md- Read when testing external services, HTTP handlers, databases, or long-running setup.
Quick Reference
| 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 |
Useful Test Failures
> 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.
No Assertion Libraries
> 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.
t.Error vs t.Fatal
> 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:
- Setup fails (DB connection, file load)
- The next assertion depends on the previous one succeeding (e.g., decode after
encode)
Never call t.Fatal/t.FailNow from a goroutine other than the test goroutine — use t.Error instead.
Table-Driven Tests
> 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:
- Use field names when cases span many lines or have same-type adjacent fields
- Include inputs in failure messages — never identify rows by index
> 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.
Test Helpers
> 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
}
Test Error Semantics
> 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)
}
Related Skills
- Error testing: See [go-error-handling](../go-error-handling/SKILL.md) when testing error semantics with
errors.Is/errors.Asor sentinel errors - Interface mocking: See [go-interfaces](../go-interfaces/SKILL.md) when creating test doubles by implementing interfaces at the consumer side
- Naming test functions: See [go-naming](../go-naming/SKILL.md) when naming test functions, subtests, or test helper utilities
- Linter integration: See [go-linting](../go-linting/SKILL.md) when running linters alongside tests in CI or pre-commit hooks
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cxuu
- Source: cxuu/golang-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.