Test-Driven Development
📋 実行前チェック(必須)
このスキルを使うべきか?
- • 新機能を実装する?
- • バグを修正する?
- • リファクタリングを行う?
- • テストコードを追加・修正する?
前提条件
- • 要件・仕様を理解しているか?
- • テストすべき振る舞いを言語化できるか?
- • テスト環境は整っているか?
禁止事項の確認
- • テストを書かずに実装しようとしていないか?
- • 「後でテストを書く」と考えていないか?
- • 既存テストを勝手に変更・削除しようとしていないか?
- • 複数のテストケースを1つのitに詰め込もうとしていないか?
- • AIが生成したテストを検証せずに使おうとしていないか?
トリガー
- •新機能実装時
- •バグ修正時
- •リファクタリング前
- •テストコード追加時
🚨 鉄則
テストを先に書く。実装コードを書く前にユーザー確認。
RED-GREEN-REFACTOR
- •RED: 失敗するテストを書く → ⚠️ ユーザー確認
- •GREEN: 最小限の実装でテストを通す
- •REFACTOR: テストを維持しながら改善
text
🛑 テスト先に書いた? → 書いてから実装前にユーザー確認した? NO → コード削除。やり直し。
TDD実践テクニック(t-wada流)
基本姿勢
- •小さなステップで進める
- •不安なところからテストを書く
- •複数のテストを同時に書かない(1つずつ)
実装戦略
- •仮実装: テストを通すためにベタ書き(
return 42)でもOK - •三角測量: 2つ目、3つ目のテストケースで一般化する
- •明白な実装: 答えが分かる場合は直接実装してもOK
TODOリスト
- •テストリストを常に更新する
- •実装中に思いついたことは即リストに追加
- •完了したらチェックを入れる
コミットルール
- •🔴 テスト追加:
test: add failing test for [feature] - •🟢 実装:
feat: implement [feature] to pass test - •🔵 リファクタ:
refactor: [description] - •テストが通ったらすぐコミット(小さく頻繁に)
⛔ テストコード変更の制限
テストは仕様。勝手に変更禁止。
許可される例外:
- •テスト追加/修正を依頼された
- •明らかな構文エラー
- •仕様が矛盾(⚠️ 要確認)
Testing Trophy
優先順位: 統合テスト > ユニットテスト > E2E
AAA パターン
typescript
it('should calculate total', () => {
// Arrange
const cart = new Cart();
cart.add({ price: 100 }, { price: 200 });
// Act
const total = cart.getTotal();
// Assert
expect(total).toBe(300);
});
🚫 禁止事項まとめ
- •テストを書かずに実装する
- •テストデータ依存の条件分岐
- •テストを実装に合わせる(逆)
- •複数テストケースを1つのitに
- •既存テストの無断変更・削除
🤖 AI生成テストの罠
よくある問題パターン
1. 自分の仮定をテストしている
- • テストは要件に基づいているか、AIの実装仮定に基づいているか?
- •AIは自分が生成したコードの「正しさ」をテストしがち
- •本来テストすべきは「要件を満たしているか」
2. エッジケースの見落とし
- • 境界値テストは含まれているか?
- • 異常系テストは含まれているか?
- • null/undefined/空文字列のケースは?
3. 意味のないアサーション
- •
expect(result).toBeDefined()だけで終わっていないか? - • 実際の値を検証しているか?
4. モックの過剰使用
- • 実装詳細をモックしすぎていないか?
- • モックが本物の振る舞いと乖離していないか?
対策
- •
テストを書く前に、テストケースを言語化する
- •「このテストは何を保証するのか?」を明文化
- •
AIが生成したテストを必ずレビューする
- •エッジケースが含まれているか確認
- •アサーションが意味のあるものか確認
- •
テストを実行して失敗を確認する(RED)
- •AIが書いたテストが本当に失敗するか確認
- •最初から通るテストは疑う