tdd について
失敗するテストを先に書くTDDスキルです。Red-Green-Refactorの手順を定め、段階ごとの確認、テスト名の付け方、フレームワーク別コマンド、よくある落とし穴を案内します。
主な機能
- 01本番コードより先に失敗テストを作成
- 02Red-Green-Refactorサイクル
- 03変更ごとのテスト実行
- 04振る舞いを表すテスト名
- 05フレームワーク別のテストコマンド
- 06TDDのよくある落とし穴への対処
活用シーン
- 01失敗する振る舞いテストから機能実装を始める
- 02実装中に既存テストの成功を維持
- 03実行可能な仕様としてテストを記述
- 04過剰なモックや複数動作のテストを回避
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ zereight/ gitlab-mcp --skill tddインストール後、Claude Code で/tddを入力して読み込まれたか確認します。
詳細
TDD — テスト駆動開発
鉄の掟:まず失敗するテストを書く。必ず。
レッド・グリーン・リファクタリングサイクル
RED → Write a failing test for the NEXT behavior
GREEN → Write ONLY enough code to make it pass (no extras)
REFACTOR → Clean up code quality (tests must stay green after every change)
REPEAT
ステップごとの手順
1. RED フェーズ
- 次に実装する最小の振る舞いを特定します
- その振る舞いを名前付きの
it()/test()/def test_として記述するテストを書きます - テストを実行します — 必ず失敗しなければなりません。成功した場合、テストが間違っています。
- 失敗メッセージが正しい失敗であることを確認します(構文エラーではないこと)
// Example: RED — test fails because function doesn't exist yet
it('returns an empty array for an empty input', () => {
const result = parseItems([]);
expect(result).toEqual([]); // FAILS: parseItems is not defined
});
2. GREEN フェーズ
- テストを成功させるために必要な最小限のコードを書きます
- 余分なロジック、デフォルト引数、「あると便利な機能」は追加しません
- すべてのテストを実行します — 新しいテストは成功し、既存のテストは壊れてはなりません
// Example: GREEN — just enough to pass
function parseItems(input: string[]): string[] {
return []; // only enough for the current test
}
3. REFACTOR フェーズ
- コードを確認します — 振る舞いを変えずに、よりすっきりさせられますか?
- 簡素化のパターンを適用します(
/ai-slop-cleanerと/coding-standardsを参照) - 変更するたびにテストを実行します。 テストが失敗したら、すぐに変更を元に戻します。
TDD ゲート — いつ止めるか
| 状況 | 対応 |
|---|---|
| テストより先にコードを書いた | 停止します。本番コードを削除し、先にテストを書きます。 |
| 初回実行でテストが成功した(コードがまだない) | テストが間違っています — まず失敗するように修正します。 |
| 1つのテストに複数の振る舞いが含まれている | 停止します。1つのテストにつき、1つの振る舞いにします。 |
| 速く進めるためにリファクタリングを省略している | 戻ります。次の機能に進む前に整理します。 |
仕様としてテストに名前を付ける
テストは実行可能なドキュメントです。完全な文として名前を付けます。
// BAD
it('test1', ...)
it('works with empty', ...)
// GOOD
it('returns empty array when input is empty', ...)
it('throws ValidationError when email is missing @', ...)
it('sends exactly one email when user registers', ...)
フレームワークのクイックリファレンス
| フレームワーク | 失敗を確認するアサーション | 単一のテストを実行 |
|---|---|---|
| Vitest | expect(x).toBe(y) | npx vitest run -t "test name" |
| Jest | expect(x).toBe(y) | npx jest -t "test name" |
| pytest | assert x == y | pytest -k "test_name" |
| cargo test | assert_eq!(x, y) | cargo test test_name |
| go test | t.Errorf(...) | go test -run TestName |
よくある TDD の落とし穴
| 落とし穴 | 修正方法 |
|---|---|
| 実装の詳細をテストする | 内部(プライベートメソッド)ではなく、振る舞い(出力)をテストします |
| 10個の振る舞いを1つのテストで検証する | テストケースを個別に分割します |
| すべてをモックする(モックの過剰使用) | システムの境界(DB、HTTP、ファイルシステム)のみをモックします |
| 三角測量を行わない | 正しい実装が導かれるように、2〜3個のテストを書きます |
| 三角測量されていない定数 | return 42 は1つのテストには合格します — 実際のロジックを強制するため、2つ目のテストを追加します |
関連項目
@test-engineer— テスト戦略、フレームワークの検出、カバレッジのギャップ分析/ultraqa— QA サイクル:テスト、検証、修正、反復/verify— エビデンスに基づく完了検証
コメント
Markdown 対応