Testing Skill
発火条件
- テスト戦略・テスト設計・テストの粒度/スコープについて相談があった場合に適用する。
- 新規機能実装時のテスト計画、テストリファクタリング、CI/CDでのテスト最適化にも適用。
- TDDの具体的な実装手順は
developer-specialistと併用する。
このSkillの基本方針
- テストピラミッド: Unit > Integration > E2E の比率を守る。上層は少なく、下層は厚く。
- 最小主義: 最初は再現・境界・不変条件のみ。実装の写経になるほど増やさない。
- 既存優先: テスト雛形・命名規約・ヘルパーは既存パターンから再利用する。
思想(判断ルール)
- ユーザー視点: テストはユーザーに見える振る舞いを検証する。実装詳細(private関数・内部状態)に依存しない。
- テストピラミッドを意識: Unitテストを土台にし、Integrationで結合点を確認し、E2Eは重要フローのみ。逆三角形(E2E過多)を避ける。
- テストは最小で最大の安心: 境界条件(null/空/最大/異常)と不変条件を押さえれば十分。網羅性の追求で保守コストを上げない。
- テストも負債になる: 壊れやすいテスト・遅いテスト・意図不明なテストは技術的負債。定期的に見直す。
テストピラミッドの判断基準
/ E2E \ ← 少なく。重要なユーザーフローのみ
/ Integration \ ← API境界・DB・外部サービス結合点
/ Unit Tests \ ← 厚く。ロジック・計算・変換・バリデーション
| 層 | 対象 | 速度 | 安定性 | 量 |
|---|---|---|---|---|
| Unit | 純粋関数、ロジック、バリデーション | 速い | 高い | 多い |
| Integration | API、DB、外部サービス連携 | 中程度 | 中程度 | 中程度 |
| E2E | ユーザーの重要フロー(ログイン→購入等) | 遅い | 低い | 少ない |
テスト設計の原則
何をテストするか
- 境界条件: null、空文字、0、最大値、負数、型境界
- 不変条件: 「この条件は常に成立する」というビジネスルール
- エラーパス: 異常入力、ネットワーク障害、タイムアウト
- 状態遷移: 重要な状態の変化(認証状態、フォーム送信等)
- 方式変更時は「無いべきものが無い」側も守る: リファクタで実装方式を変えると、それまで「たまたまそうだった」性質(例: リソースの収録範囲、データの形)が仕組みの生命線に昇格することがある。既存テストは「在るべきものが在る」しか守っていないことが多いので、方式変更時は不変条件をガードするテストを追加する
何をテストしないか
- 実装詳細(private関数のテスト、内部状態の直接検証)
- フレームワーク/ライブラリ自体の動作
- 外部サービスの可用性(モックで代替)
- 全パスの網羅(コストに見合わない場合)
テストの命名
// 良い例: 「何が」「どうなったとき」「どうなるか」
test("ユーザー登録_メールが空のとき_バリデーションエラーを返す")
test("カート_商品追加_合計金額が更新される")
// 悪い例: 実装詳細に依存
test("validateEmail関数がfalseを返す")
出力フォーマット(必ずこの順)
- テスト方針(何をどの粒度でテストするか)
- 理由(リスク / コスト / 保守性のバランス)
- テスト設計(テストケース一覧 / 境界条件 / モック戦略)
- TDDステップ(RED→GREEN→REFACTORの具体的手順)
- チェックリスト(実装前に確認)
- 落とし穴(避けるべき)
チェックリスト
- RED→GREEN→REFACTOR の順序が守られているか(テストが先)
- テストはユーザー視点の振る舞いを検証しているか(実装詳細に依存していないか)
- 境界条件(null/空/最大/異常)が最低限押さえられているか
- テストピラミッドの比率が適切か(E2Eに偏っていないか)
- テストが独立しているか(他のテストの実行順に依存していないか)
- テスト名が「何が・どうなったとき・どうなるか」を表しているか
- モック/スタブの範囲が最小限か(過度なモックは信頼性を下げる)
よくある落とし穴
- テストが「実装の写経」になり、安心が増えていない(ロジックのコピペ検証)
- E2Eテストを大量に書いて、CIが遅くなり開発体験が悪化する
- モックを使いすぎて、結合時に初めて問題が発覚する
- テストカバレッジの数値目標を追い、意味のないテストが増える
sleep/ 固定待機でテストを安定させようとする(根本原因を隠す)- テストデータが共有されていて、テスト順序で結果が変わる
vite.configにランタイム系プラグイン(エッジ実行環境系等)があると、テストランナーが環境設定の衝突で起動失敗する。テスト専用設定ファイルを分離し、プラグインなしの軽量環境でユニットテストを回す(ランタイム結合の確認は開発サーバー/プレビューに寄せる)