[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F3JX96PQR3PCDPKPT5430T":3,"skill-same:01M6F3JX96PQR3PCDPKPT5430T":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":53,"commitSha":54,"skillDirectory":55,"forksCount":56,"repositoryHtmlUrl":57,"repositoryHomepageUrl":58,"ownerHtmlUrl":59,"ownerBlogUrl":6,"ownerDescription":60,"updatedAt":61,"install":62,"resources":75},"01M6F3JX96PQR3PCDPKPT5430T","go-testing",null,"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).","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fcxuu\u002Fgolang-skills\u002Fgo-testing\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"go","go testing","testing","Bash","with","style","cmp","tests","diff","use","write","parallel","benchmark","code","performance testing","test","performance","github","google","writing","2026-11-10 10:12:30",false,"---\nname: go-testing\ndescription: 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).\nlicense: Apache-2.0\ncompatibility: Uses github.com\u002Fgoogle\u002Fgo-cmp for cmp.Diff comparisons\nmetadata:\n  sources: \"Google Style Guide, Uber Style Guide\"\nallowed-tools: Bash(bash:*)\n---\n\n# Go Testing\n\n## Quick Reference\n\n| Pattern | Use When |\n|---------|----------|\n| `t.Error` | Default — report failure, keep running |\n| `t.Fatal` | Setup failed or continuing is meaningless |\n| `cmp.Diff` | Comparing structs, slices, maps, protos |\n| Table-driven | Many cases share identical logic |\n| Subtests | Need filtering, parallel execution, or naming |\n| `t.Helper()` | Any test helper function (call as first statement) |\n| `t.Cleanup()` | Teardown in helpers instead of defer |\n\n---\n\n## Useful Test Failures\n\n> **Normative**: Test failures must be diagnosable without reading the test\n> source.\n\nEvery failure message must include: function name, inputs, actual (got), and\nexpected (want). Use the format `YourFunc(%v) = %v, want %v`.\n\n```go\n\u002F\u002F Good:\nt.Errorf(\"Add(2, 3) = %d, want %d\", got, 5)\n\n\u002F\u002F Bad: Missing function name and inputs\nt.Errorf(\"got %d, want %d\", got, 5)\n```\n\nAlways print got before want: `got %v, want %v` — never reversed.\n\n---\n\n## No Assertion Libraries\n\n> **Normative**: Do not use assertion libraries. Use `cmp.Diff` for complex\n> comparisons.\n\n```go\nif diff := cmp.Diff(want, got); diff != \"\" {\n    t.Errorf(\"GetPost() mismatch (-want +got):\\n%s\", diff)\n}\n```\n\nFor protocol buffers, add `protocmp.Transform()` as a cmp option. Always\ninclude the direction key `(-want +got)` in diff messages. Avoid comparing\nJSON\u002Fserialized output — compare semantically instead.\n\n> Read [references\u002FTEST-HELPERS.md](references\u002FTEST-HELPERS.md) when writing\n> custom comparison helpers or domain-specific test utilities.\n\n---\n\n## t.Error vs t.Fatal\n\n> **Normative**: Use `t.Error` by default to report all failures in one run.\n> Use `t.Fatal` only when continuing is impossible.\n\n**Choose `t.Fatal` when:**\n- Setup fails (DB connection, file load)\n- The next assertion depends on the previous one succeeding (e.g., decode after\n  encode)\n\n**Never call `t.Fatal`\u002F`t.FailNow` from a goroutine** other than the test\ngoroutine — use `t.Error` instead.\n\n> Read [references\u002FTEST-HELPERS.md](references\u002FTEST-HELPERS.md) when writing\n> helpers that need to choose between t.Error and t.Fatal, or for detailed\n> examples of both.\n\n---\n\n## Table-Driven Tests\n\n> See `assets\u002Ftable-test-template.go` when scaffolding a new table-driven test and need the canonical struct, loop, and subtest layout.\n\n> **Advisory**: Use table-driven tests when many cases share identical logic.\n\n**Use table tests when:** all cases run the same code path with no conditional\nsetup, mocking, or assertions. A single `shouldErr` bool is acceptable.\n\n**Don't use table tests when:** cases need complex setup, conditional mocking,\nor multiple branches — write separate test functions instead.\n\n**Key rules:**\n- Use field names when cases span many lines or have same-type adjacent fields\n- Include inputs in failure messages — never identify rows by index\n\n> Read [references\u002FTABLE-DRIVEN-TESTS.md](references\u002FTABLE-DRIVEN-TESTS.md)\n> when writing table-driven tests, subtests, or parallel tests.\n\n> **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.\n\n---\n\n## Test Helpers\n\n> **Normative**: Test helpers must call `t.Helper()` first and use `t.Cleanup()`\n> for teardown.\n\n```go\nfunc setupTestDB(t *testing.T) *sql.DB {\n    t.Helper()\n    db, err := sql.Open(\"sqlite3\", \":memory:\")\n    if err != nil {\n        t.Fatalf(\"Could not open database: %v\", err)\n    }\n    t.Cleanup(func() { db.Close() })\n    return db\n}\n```\n\n> Read [references\u002FTEST-HELPERS.md](references\u002FTEST-HELPERS.md) when writing\n> test helpers, cleanup functions, or custom comparison utilities.\n\n---\n\n## Test Error Semantics\n\n> **Advisory**: Test error semantics, not error message strings.\n\n```go\n\u002F\u002F Bad: Brittle string comparison\nif err.Error() != \"invalid input\" { ... }\n\n\u002F\u002F Good: Semantic check\nif !errors.Is(err, ErrInvalidInput) { ... }\n```\n\nFor simple presence checks when specific semantics don't matter:\n\n```go\nif gotErr := err != nil; gotErr != tt.wantErr {\n    t.Errorf(\"f(%v) error = %v, want error presence = %t\", tt.input, err, tt.wantErr)\n}\n```\n\n---\n\n## Test Organization\n\n> Read [references\u002FTEST-ORGANIZATION.md](references\u002FTEST-ORGANIZATION.md) when\n> working with test doubles, choosing test package placement, or scoping test\n> setup.\n\n> Read [references\u002FVALIDATION-APIS.md](references\u002FVALIDATION-APIS.md) when\n> designing reusable test validation functions.\n\n---\n\n## Integration Testing\n\n> Read [references\u002FINTEGRATION.md](references\u002FINTEGRATION.md) when writing\n> TestMain, acceptance tests, or tests that need real HTTP\u002FRPC transports.\n\n---\n\n## Available Scripts\n\n- **`scripts\u002Fgen-table-test.sh`** — Generates a table-driven test scaffold\n\n```bash\nbash scripts\u002Fgen-table-test.sh ParseConfig config > config\u002Fparse_config_test.go\nbash scripts\u002Fgen-table-test.sh --parallel ParseConfig config      # with t.Parallel()\nbash scripts\u002Fgen-table-test.sh --output config\u002Fparse_config_test.go ParseConfig config\n```\n\n---\n\n## Related Skills\n\n- **Error testing**: See [go-error-handling](..\u002Fgo-error-handling\u002FSKILL.md) when testing error semantics with `errors.Is`\u002F`errors.As` or sentinel errors\n- **Interface mocking**: See [go-interfaces](..\u002Fgo-interfaces\u002FSKILL.md) when creating test doubles by implementing interfaces at the consumer side\n- **Naming test functions**: See [go-naming](..\u002Fgo-naming\u002FSKILL.md) when naming test functions, subtests, or test helper utilities\n- **Linter integration**: See [go-linting](..\u002Fgo-linting\u002FSKILL.md) when running linters alongside tests in CI or pre-commit hooks\n\n","# Go Testing\n\n## Quick Reference\n\n| Pattern | Use When |\n|---------|----------|\n| `t.Error` | Default — report failure, keep running |\n| `t.Fatal` | Setup failed or continuing is meaningless |\n| `cmp.Diff` | Comparing structs, slices, maps, protos |\n| Table-driven | Many cases share identical logic |\n| Subtests | Need filtering, parallel execution, or naming |\n| `t.Helper()` | Any test helper function (call as first statement) |\n| `t.Cleanup()` | Teardown in helpers instead of defer |\n\n---\n\n## Useful Test Failures\n\n> **Normative**: Test failures must be diagnosable without reading the test\n> source.\n\nEvery failure message must include: function name, inputs, actual (got), and\nexpected (want). Use the format `YourFunc(%v) = %v, want %v`.\n\n```go\n\u002F\u002F Good:\nt.Errorf(\"Add(2, 3) = %d, want %d\", got, 5)\n\n\u002F\u002F Bad: Missing function name and inputs\nt.Errorf(\"got %d, want %d\", got, 5)\n```\n\nAlways print got before want: `got %v, want %v` — never reversed.\n\n---\n\n## No Assertion Libraries\n\n> **Normative**: Do not use assertion libraries. Use `cmp.Diff` for complex\n> comparisons.\n\n```go\nif diff := cmp.Diff(want, got); diff != \"\" {\n    t.Errorf(\"GetPost() mismatch (-want +got):\\n%s\", diff)\n}\n```\n\nFor protocol buffers, add `protocmp.Transform()` as a cmp option. Always\ninclude the direction key `(-want +got)` in diff messages. Avoid comparing\nJSON\u002Fserialized output — compare semantically instead.\n\n> Read [references\u002FTEST-HELPERS.md](references\u002FTEST-HELPERS.md) when writing\n> custom comparison helpers or domain-specific test utilities.\n\n---\n\n## t.Error vs t.Fatal\n\n> **Normative**: Use `t.Error` by default to report all failures in one run.\n> Use `t.Fatal` only when continuing is impossible.\n\n**Choose `t.Fatal` when:**\n- Setup fails (DB connection, file load)\n- The next assertion depends on the previous one succeeding (e.g., decode after\n  encode)\n\n**Never call `t.Fatal`\u002F`t.FailNow` from a goroutine** other than the test\ngoroutine — use `t.Error` instead.\n\n> Read [references\u002FTEST-HELPERS.md](references\u002FTEST-HELPERS.md) when writing\n> helpers that need to choose between t.Error and t.Fatal, or for detailed\n> examples of both.\n\n---\n\n## Table-Driven Tests\n\n> See `assets\u002Ftable-test-template.go` when scaffolding a new table-driven test and need the canonical struct, loop, and subtest layout.\n\n> **Advisory**: Use table-driven tests when many cases share identical logic.\n\n**Use table tests when:** all cases run the same code path with no conditional\nsetup, mocking, or assertions. A single `shouldErr` bool is acceptable.\n\n**Don't use table tests when:** cases need complex setup, conditional mocking,\nor multiple branches — write separate test functions instead.\n\n**Key rules:**\n- Use field names when cases span many lines or have same-type adjacent fields\n- Include inputs in failure messages — never identify rows by index\n\n> Read [references\u002FTABLE-DRIVEN-TESTS.md](references\u002FTABLE-DRIVEN-TESTS.md)\n> when writing table-driven tests, subtests, or parallel tests.\n\n> **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.\n\n---\n\n## Test Helpers\n\n> **Normative**: Test helpers must call `t.Helper()` first and use `t.Cleanup()`\n> for teardown.\n\n```go\nfunc setupTestDB(t *testing.T) *sql.DB {\n    t.Helper()\n    db, err := sql.Open(\"sqlite3\", \":memory:\")\n    if err != nil {\n        t.Fatalf(\"Could not open database: %v\", err)\n    }\n    t.Cleanup(func() { db.Close() })\n    return db\n}\n```\n\n> Read [references\u002FTEST-HELPERS.md](references\u002FTEST-HELPERS.md) when writing\n> test helpers, cleanup functions, or custom comparison utilities.\n\n---\n\n## Test Error Semantics\n\n> **Advisory**: Test error semantics, not error message strings.\n\n```go\n\u002F\u002F Bad: Brittle string comparison\nif err.Error() != \"invalid input\" { ... }\n\n\u002F\u002F Good: Semantic check\nif !errors.Is(err, ErrInvalidInput) { ... }\n```\n\nFor simple presence checks when specific semantics don't matter:\n\n```go\nif gotErr := err != nil; gotErr != tt.wantErr {\n    t.Errorf(\"f(%v) error = %v, want error presence = %t\", tt.input, err, tt.wantErr)\n}\n```\n\n---\n\n## Test Organization\n\n> Read [references\u002FTEST-ORGANIZATION.md](references\u002FTEST-ORGANIZATION.md) when\n> working with test doubles, choosing test package placement, or scoping test\n> setup.\n\n> Read [references\u002FVALIDATION-APIS.md](references\u002FVALIDATION-APIS.md) when\n> designing reusable test validation functions.\n\n---\n\n## Integration Testing\n\n> Read [references\u002FINTEGRATION.md](references\u002FINTEGRATION.md) when writing\n> TestMain, acceptance tests, or tests that need real HTTP\u002FRPC transports.\n\n---\n\n## Available Scripts\n\n- **`scripts\u002Fgen-table-test.sh`** — Generates a table-driven test scaffold\n\n```bash\nbash scripts\u002Fgen-table-test.sh ParseConfig config > config\u002Fparse_config_test.go\nbash scripts\u002Fgen-table-test.sh --parallel ParseConfig config      # with t.Parallel()\nbash scripts\u002Fgen-table-test.sh --output config\u002Fparse_config_test.go ParseConfig config\n```\n\n---\n\n## Related Skills\n\n- **Error testing**: See [go-error-handling](..\u002Fgo-error-handling\u002FSKILL.md) when testing error semantics with `errors.Is`\u002F`errors.As` or sentinel errors\n- **Interface mocking**: See [go-interfaces](..\u002Fgo-interfaces\u002FSKILL.md) when creating test doubles by implementing interfaces at the consumer side\n- **Naming test functions**: See [go-naming](..\u002Fgo-naming\u002FSKILL.md) when naming test functions, subtests, or test helper utilities\n- **Linter integration**: See [go-linting](..\u002Fgo-linting\u002FSKILL.md) when running linters alongside tests in CI or pre-commit hooks\n\n",{"name":5,"license":15,"metadata":49,"description":7,"allowed-tools":51,"compatibility":52},{"sources":50},"Google Style Guide, Uber Style Guide","Bash(bash:*)","Uses github.com\u002Fgoogle\u002Fgo-cmp for cmp.Diff comparisons","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fcxuu\u002Fgolang-skills\u002Fgo-testing",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill go-testing",{"tool":68,"command":69},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill go-testing",{"tool":71,"command":72},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill go-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fcxuu\u002Fgolang-skills\u002Fgo-testing\u002FSKILL.md",true,[],[77,90,100,109,115,122],{"skillNo":78,"name":79,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":86,"publishedAt":44},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[83],{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[87,88,89],"model","model hierarchy","model hierarchy skill",{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":96,"publishedAt":44},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[95],{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},[97,98,99],"MCP","zoom","zoom mcp",{"skillNo":101,"name":102,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":44},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[106,107,108,98],"sdk","zoom apps sdk","apps",{"skillNo":110,"name":111,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":44},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[111],{"skillNo":116,"name":117,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":121,"publishedAt":44},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[120],{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},[117],{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":80,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":44},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[124]]