Use when writing or reviewing Go tests - standard testing package, table-driven tests, subtests, test helpers, httptest, benchmarks, fuzz testing, and interface-based mocking.
Resolve SKILL_DIR to the absolute directory containing this SKILL.md, as
shown by the current host, before using any bundled path below.
Before a shell command uses $SKILL_DIR, assign it in that command or replace
it with the resolved path. It is not a host-exported environment variable.
Standard Go testing package patterns and common libraries. For shared test quality principles (philosophy, smells, mocking decisions), see testing-patterns.
| Need | Reference File | Sections to Read |
|------|---------------|-----------------|
| Go testing patterns | $SKILL_DIR/../testing-patterns/references/go-testing-patterns.md | Full file (~420L, manageable) |
| Behavior vs implementation | $SKILL_DIR/../testing-patterns/references/test-philosophy.md | ## The Fundamental Shift + ## Four Core Principles |
| Flaky/brittle tests | $SKILL_DIR/../testing-patterns/references/test-smells.md | ## The Six Major Test Smells (relevant subsection) |
| Mock usage decisions | $SKILL_DIR/../testing-patterns/references/mocking-strategies.md | ## The Mocking Decision Framework |
| AAA pattern/naming | $SKILL_DIR/../testing-patterns/references/test-structure.md | ## The AAA Pattern + ## Test Naming Conventions |
| Test data strategy | $SKILL_DIR/../testing-patterns/references/test-data.md | ## Factories + ## Builders |
How to read sections: Grep for heading to find line number, Read with offset+limit.
| Use | Instead Of | Why |
|-----|-----------|-----|
| t.Fatalf("got %v, want %v", got, want) | t.Errorf for preconditions | Stops test when continuing is meaningless |
| require.NoError(t, err) | if err != nil { t.Fatal(err) } | Concise with testify (optional) |
| t.Run(tt.name, func(t *testing.T) {...}) | Flat loop body | Isolates cases, enables -run filtering |
| t.Helper() | Nothing | Failures point to caller, not helper |
| t.Setenv("KEY", "val") | os.Setenv + defer restore | Auto-restored, goroutine-safe |
| t.TempDir() | os.MkdirTemp + defer remove | Auto-cleaned after test |
| t.Cleanup(fn) | defer fn() | Runs even on t.FailNow/t.Fatal |
| httptest.NewServer(handler) | Real HTTP calls | Fast, deterministic, no network |
| Pattern | Why Harmful | Fix |
|---------|------------|-----|
| Missing t.Helper() in helpers | Wrong failure location | Add as first line in helper functions |
| os.Setenv without t.Setenv | Env leaks between tests | Use t.Setenv() (Go 1.17+) |
| Table tests without t.Run | Can't isolate or run individual cases | Wrap body in t.Run(tt.name, ...) |
| Anonymous test cases | Hard to identify which failed | Add name field to test table |
| t.Parallel() + shared mutation | Data race | Isolate state per subtest |
| t.Parallel() + t.Setenv | Runtime panic | Use config structs instead |
| fmt.Println in tests | Lost in parallel output | Use t.Log/t.Logf |
| Manual temp dirs | Leak on failure | Use t.TempDir() |
func TestParse(t *testing.T) {
tests := []struct {
name string
input string
want Result
wantErr bool
}{
{name: "valid", input: "abc", want: Result{Value: "abc"}},
{name: "empty", input: "", wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Parse(tt.input)
if (err != nil) != tt.wantErr {
t.Fatalf("Parse(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
if !tt.wantErr && got != tt.want {
t.Errorf("Parse(%q) = %v, want %v", tt.input, got, tt.want)
}
})
}
}
Go prefers small interfaces + hand-written test doubles over mocking frameworks:
type Store interface {
Get(ctx context.Context, id string) (*Item, error)
}
type fakeStore struct {
items map[string]*Item
}
func (f *fakeStore) Get(_ context.Context, id string) (*Item, error) {
item, ok := f.items[id]
if !ok {
return nil, ErrNotFound
}
return item, nil
}
Use gomock/mockall only when the interface has many methods.
npx skills add vladolaru/go-testing-patterns下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer