mcpField
T
tdd-mastery

tdd-mastery

github.com/rohitg00テスト・品質2.8k185 回インストール24 週間前に更新
リポジトリ

tdd-mastery について

JavaScript、Python、Go でテスト駆動開発を行う開発者向けのテストスキルガイドです。テスト構成、カバレッジ、モック、アンチパターンも扱います。

主な機能

  1. 01Red-Green-Refactor サイクル
  2. 02Arrange-Act-Assert 構成
  3. 03Jest と Vitest のパターン
  4. 04pytest と Go のテストパターン
  5. 05カバレッジとテストレベルの指針
  6. 06モックの原則とアンチパターン

活用シーン

  1. 01実装前のテスト計画
  2. 02対応言語ごとのテスト構成
  3. 03カバレッジと不安定なテスト対応の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rohitg00/awesome-claude-code-toolkit --skill tdd-mastery

インストール後、Claude Code で/tdd-masteryを入力して読み込まれたか確認します。

詳細

TDD の習熟

基本サイクル:レッド・グリーン・リファクタリング

  1. レッド - 望ましい動作を定義する、失敗するテストを書きます
  2. グリーン - テストを通すために必要な最小限のコードを書きます
  3. リファクタリング - テストを通したままコードを整理します

まず失敗するテストを書かずに、本番コードを書いてはいけません。各サイクルは 2~10 分で行います。

テストの構成

Arrange-Act-Assert パターンを一貫して使います:

Arrange: Set up test data and dependencies
Act:     Execute the behavior under test
Assert:  Verify the expected outcome

テストには test_<unit>_<scenario>_<expected_result> または it("should <behavior> when <condition>") の形式で名前を付けます。

Jest / Vitest のパターン

describe("OrderService", () => {
  it("should apply discount when order exceeds threshold", () => {
    const order = createOrder({ items: [{ price: 150, qty: 1 }] });
    const result = applyDiscount(order, { threshold: 100, percent: 10 });
    expect(result.total).toBe(135);
  });

  it("should throw when applying discount to empty order", () => {
    const order = createOrder({ items: [] });
    expect(() => applyDiscount(order, defaultDiscount)).toThrow(EmptyOrderError);
  });
});

モックには vi.fn() / jest.fn() を使います。モジュールのモック化より、依存性注入を優先します。共通のセットアップには beforeEach を使い、テスト間で変更可能な状態を共有しないでください。

pytest のパターン

@pytest.fixture
def db_session():
    session = create_test_session()
    yield session
    session.rollback()

def test_create_user_stores_hashed_password(db_session):
    user = UserService(db_session).create(email="[email protected]", password="secret")
    assert user.password_hash != "secret"
    assert verify_password("secret", user.password_hash)

@pytest.mark.parametrize("input,expected", [
    ("", False),
    ("short", False),
    ("ValidPass1!", True),
])
def test_password_validation(input, expected):
    assert validate_password(input) == expected

例外には pytest.raises を使います。共通のフィクスチャには conftest.py を使います。時間のかかるテストには @pytest.mark.slow を付けます。

Go のテストパターン

func TestParseConfig(t *testing.T) {
    tests := []struct {
        name    string
        input   string
        want    Config
        wantErr bool
    }{
        {"valid yaml", "port: 8080", Config{Port: 8080}, false},
        {"empty input", "", Config{}, true},
        {"invalid port", "port: -1", Config{}, true},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := ParseConfig([]byte(tt.input))
            if (err != nil) != tt.wantErr {
                t.Errorf("ParseConfig() error = %v, wantErr %v", err, tt.wantErr)
                return
            }
            if !tt.wantErr && got != tt.want {
                t.Errorf("ParseConfig() = %v, want %v", got, tt.want)
            }
        })
    }
}

通常はテーブル駆動テストを使います。テスト用のユーティリティ関数では t.Helper() を使います。チームですでに使用している場合に限り、testify/assert を使います。

テストレベル

レベル範囲速度依存関係
単体単一の関数/クラス<100msなし(すべてモック化)
統合モジュール間の境界<5s実際の DB、実際のファイルシステム
E2Eユーザーフロー全体<30sフルスタック

目標比率:単体 70%、統合 20%、E2E 10%。

カバレッジのルール

  • CI でラインカバレッジ 80%以上を必須にします
  • ラインカバレッジだけでなく、ブランチカバレッジも追跡します
  • 生成コード、型定義、設定ファイルは対象から除外します
  • カバレッジの数値を満たすためだけにテストを書かず、動作をテストします
# Jest/Vitest
vitest run --coverage --coverage.thresholds.lines=80 --coverage.thresholds.branches=75

# pytest
pytest --cov=src --cov-fail-under=80 --cov-branch

# Go
go test -coverprofile=cover.out -coverpkg=./... ./...
go tool cover -func=cover.out

モックのガイドライン

  • 境界でモック化します:HTTP クライアント、データベース、ファイルシステム、時計
  • テスト対象のユニットはモック化しません
  • リポジトリには、モックよりフェイク(インメモリ実装)を優先します
  • モックの呼び出し回数ではなく、動作を検証します
  • t.Cleanup / afterEach を使って共有モックをリセットします

避けるべきアンチパターン

  • 動作ではなく実装の詳細をテストする
  • コードを削除しても通るテスト(同語反復的なテスト)
  • テストケース間で変更可能な状態を共有する
  • 不安定なテストを修正せずに放置する
  • 非公開メソッドを直接テストする
  • 意図を分かりにくくする、巨大なテストのセットアップ

コメント