MCP HubMCP Hub
SKILL·17F695

go-test-table-driven

eduardo-sl
更新日 27 days ago
5 閲覧
69
9
69
GitHubで表示
テストtestingdesigndata

について

このClaudeスキルは、Go言語におけるテーブル駆動テストの実装とリファクタリングに関する専門的なガイダンスを提供します。構造体設計、サブテストの命名、テストマトリックスなどの高度なパターン、およびこのアプローチの適切な使用判断についてベストプラクティスを網羅しています。一般的なテスト戦略や他のテストタイプではなく、テーブル駆動テストの作成、レビュー、整理に特化してご利用ください。

クイックインストール

Claude Code

推奨
メイン
npx skills add eduardo-sl/go-agent-skills -a claude-code
プラグインコマンド代替
/plugin add https://github.com/eduardo-sl/go-agent-skills
Git クローン代替
git clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-test-table-driven

このコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします

ドキュメント

Go Table-Driven Tests

Table-driven tests are a powerful Go idiom — when used correctly. Most codebases either underuse them (10 copy-paste tests) or overuse them (complex branching logic in a 200-line struct). This skill covers the sweet spot.

Detailed reference material, loaded on demand:

  • references/patterns.md — full worked examples: canonical tables, wantErr/wantErrIs, parallel tables, map-based tables, error-only tables, struct alignment for readability.
  • references/refactoring.md — recognizing bloated tables and rewriting them as explicit subtests, with before/after examples.

Read a reference file only when the summary below is not enough for the task at hand.

1. When Table-Driven Tests Shine

Use a table only when ALL of these are true:

  • Same function under test across all cases
  • Same assertion pattern — input in, output out, compare
  • Cases differ only in data, not in setup or verification logic
  • 3+ cases — fewer than 3, explicit tests are clearer

Canonical use case: pure functions, parsers, validators, formatters.

func TestParseSize(t *testing.T) {
    tests := []struct {
        name    string
        input   string
        want    int64
        wantErr bool
    }{
        {name: "plain bytes", input: "1024", want: 1024},
        {name: "kilobytes suffix", input: "4KB", want: 4096},
        {name: "empty string", input: "", wantErr: true},
        {name: "negative size", input: "-1", wantErr: true},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := ParseSize(tt.input)
            if tt.wantErr {
                require.Error(t, err)
                return
            }
            require.NoError(t, err)
            assert.Equal(t, tt.want, got)
        })
    }
}

Every case has the same shape, the loop body is a few lines, and adding a case is one struct literal. No branching, no conditionals.

2. When NOT to Use Table-Driven Tests

  • Complex per-case setupsetupMock/setupFunc function fields in the struct mean the table is hiding complexity. Write explicit subtests.
  • Fewer than 3 cases — the struct definition is more code than two plain test functions.
  • Multiple branching pathsif tt.shouldError / if tt.wantRedirect in the loop body means each branch is a different test pretending to share a structure. Split it.

See references/refactoring.md for before/after rewrites of each smell.

3. Struct Design Rules

  1. Every field must vary between at least 2 cases. A field with the same value everywhere is setup — move it outside the table.
  2. Name the name field as a short sentence describing the scenario: "returns error for negative amount", not "case1" or "success".
  3. wantErr bool for "should it error?" — check it first and return early in the loop body.
  4. wantErrIs error with a sentinel when the caller must detect a specific error; assert with require.ErrorIs.
  5. ≤5 fields. More means the scenario is too complex for a table — split into separate test functions.

Full field-pattern examples are in references/patterns.md.

4. The Loop Body Must Be Trivial

The point of a table test is identical execution logic for every case. Keep the loop body under ~10 lines: call, error check, comparison. If it accumulates conditionals or per-case setup, the table has outgrown its usefulness — refactor into explicit subtests.

5. Parallel Table Tests

for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        t.Parallel()
        got := Transform(tt.input)
        assert.Equal(t, tt.want, got)
    })
}
  • Go 1.22+ scopes the loop variable per iteration — tt := tt capture is unnecessary. For Go <1.22 the capture is still required.
  • Only use t.Parallel() when the function under test has no side effects and no shared mutable state.

6. Refactoring Bloated Tables

SymptomFix
Struct has 8+ fieldsSplit into multiple test functions by scenario
setupFunc field in structExtract to separate subtests with explicit setup
if tt.shouldX in loop bodyEach branch is a different test — split it
Same 3 fields identical in every caseMove to shared setup outside the table
Adding a case requires understanding all othersTable has grown beyond its useful life

Decision Flowchart

  1. Is the function pure (input → output, no side effects)? Yes → table test is probably ideal. Go to 2. No → consider explicit subtests first.

  2. Do all cases share the exact same assertion pattern? Yes → table test. Go to 3. No → explicit subtests.

  3. Can each case be expressed in ≤5 struct fields? Yes → table test. No → split by scenario into separate test functions.

  4. Is the loop body ≤10 lines? Yes → you're golden. No → the table is hiding complexity. Refactor.

Verification Checklist

  1. Table struct has only fields that vary between cases
  2. Every case has a descriptive name field
  3. Loop body is ≤10 lines with no branching
  4. No setupFunc or mockFunc fields in the struct
  5. wantErr is a simple bool or sentinel, not a string match
  6. Cases cover: happy path, error path, edge cases (empty, nil, zero, max)
  7. t.Run wraps each case for named subtests
  8. t.Parallel() used only when function is side-effect-free

GitHub リポジトリ

eduardo-sl/go-agent-skills
パス: skills/(testing)/go-test-table-driven
0
FAQ

よくある質問

go-test-table-driven Skillとは何ですか?

go-test-table-driven はeduardo-sl が作成した Claude Skillです。Skillは、Claudeが必要に応じて読み込む指示とリソースをまとめ、追加の指示なしで go-test-table-driven に関連するタスクを実行できるようにします。

go-test-table-driven をインストールするには?

このページのインストールコマンドを使用してください。go-test-table-driven をプラグインとして Claude Code に追加するか、リポジトリを skills ディレクトリにクローンし、Claudeを再起動してSkillを読み込みます。

go-test-table-driven はどのカテゴリに属しますか?

go-test-table-driven は テスト カテゴリに属します。

go-test-table-driven は無料で利用できますか?

はい。go-test-table-driven は AIMCP に掲載されており、無料でインストールできます。

関連スキル

evaluating-llms-harness
テスト

このClaudeスキルは、lm-evaluation-harnessを実行し、MMLUやGSM8Kなど60以上の標準化学術タスクでLLMをベンチマークします。開発者がモデルの品質を比較し、トレーニングの進捗を追跡し、学術的な結果を報告するために設計されています。このツールはHuggingFaceやvLLMモデルを含む様々なバックエンドをサポートしています。

スキルを見る
cloudflare-cron-triggers
テスト

このスキルは、cron式を使用してWorkersをスケジュールするためのCloudflare Cron Triggersの実装に関する包括的な知識を提供します。定期的なタスクの設定、メンテナンスジョブ、自動化されたワークフローの構築を網羅し、無効なcron式やタイムゾーン問題といった一般的な課題への対処法も含みます。開発者はこれを使用して、スケジュールされたハンドラーの設定、cronトリガーのテスト、WorkflowsやGreen Computeとの連携を構成できます。

スキルを見る
webapp-testing
テスト

このClaude Skillは、Playwrightベースのツールキットを提供し、Pythonスクリプトを通じてローカルWebアプリケーションのテストを可能にします。フロントエンドの検証、UIデバッグ、スクリーンショット撮影、ログ表示を実現し、サーバーライフサイクルを管理します。ブラウザ自動化タスクにご利用いただけますが、コンテキストの汚染を避けるため、スクリプトのソースコードを読むのではなく直接実行してください。

スキルを見る
finishing-a-development-branch
テスト

このスキルは、開発者がテストの合格を確認し、構造化された統合オプションを提示することで、完成した作業を仕上げることを支援します。実装が完了した後のマージ、PR作成、ブランチの整理といったワークフローを案内します。コードが準備できてテスト済みの際に使用し、開発プロセスを体系的に完了させましょう。

スキルを見る