統合テストとE2Eテストを設計。モック境界と振る舞い検証ルールを適用。E2Eテスト、統合テスト作成時に使用。
| テスト種別 | 目的 | スコープ | 外部依存 | ファイル形式 | 実装タイミング |
|---|---|---|---|---|---|
| 統合 | in-processでのコンポーネント間連携を検証 | システムの部分的な統合(in-processモジュール。UIコンポーネントではReact/TSのRTL+MSWなど) | モックまたはin-process | *.int.test.ts |
実装と並行して作成 |
| fixture-e2e | 決定論的フィクスチャを用いてブラウザ上の振る舞いを検証 | モックバックエンドまたはフィクスチャ駆動の状態によるUIフロー全体 | モック/フィクスチャのみ — ライブサービスなし | *.fixture-e2e.test.ts |
UI機能と並行して作成 |
| service-integration-e2e | 起動済みスタックでしか確認できない契約を検証 | サービスをまたいだシステム全体 | ローカルの実サービスまたはservice-levelスタブ | *.service-e2e.test.ts |
必要なサービスが存在してから実行 |
レーン選択(E2Eのみ):
受け入れ済みの証明義務から始め、各義務をその失敗を検出できる最も安価な境界に割り当て、重複するカバレッジを除き、残った個別の失敗をすべてカバーする最小のセットを残す。テスト数はその証明義務から決める。ある機能について、特定のレーンにテストが1件もないことも妥当である。
統合/E2Eテストの候補は、次の情報を示す:
単独で観測できる振る舞いはユニット/コンポーネント検証へ振り分ける。制御された環境を利用できない場合は、service-integration-e2eの証明前提として記録する。
プロジェクトのテスト対象パターンに一致するファイルをコミットする場合、そのファイルはテストランナー上で有効な状態を保たなければならない。検出したフレームワークにおける最小のpendingスイート(describeとit.todo、またはその同等物)を用い、テストフレームワークのimportと必須コメントのみを含める。実装タスクがpendingのケースを置き換え、実装と同時にアプリケーションのimport、アサーション、フィクスチャ、モックセットアップを追加する。
各テストに以下の注釈を含めること。
// AC: "[受入条件原文]"
// Behavior: [トリガー] -> [処理] -> [観測可能な結果]
// @lane: integration | fixture-e2e | service-integration-e2e
// @dependency: none | [コンポーネント名] | full-ui (mocked backend) | full-system
// @real-dependency: [コンポーネント名](任意。テスト境界で非モックのセットアップを指定した場合)
// Primary failure mode: [実装後のテストが検出すべき具体的なリグレッション]
// Proof obligation: [実装後のテストでアサートすべき境界と観測可能な状態]
// Verification items: [義務が満たされたことを示す観測結果]
@lane 選択ルール:
integration — in-processでのコンポーネント間連携。ブラウザは使用しない(例: React/TSではRTL+MSW、その他の言語ではin-processのモジュール/ハンドラ統合)fixture-e2e — モックバックエンドまたはフィクスチャ駆動の状態に対するブラウザレベルのUI検証。@dependencyは通常full-ui (mocked backend)service-integration-e2e — 起動済みのローカルサービスまたはスタブに対するブラウザレベルまたはエンドツーエンドの検証。@dependencyはfull-system// Property: `[検証式]`
// fast-check: fc.property(fc.[arbitrary], (input) => [不変条件])
受け入れ済みの振る舞いとリポジトリの証明境界を基準に選定する。プロダクト分析や数値化した価値見積もりは不要である。根拠となる情報源とリポジトリのエビデンスを確認しても、受け入れ済みの振る舞いまたは必要な契約が未確定の場合はエスカレーションする。
Property注釈がある場合、fast-check必須:
fc.assert(fc.property(...))形式で記述// fast-check:コメントをそのまま実装に反映振る舞い記述の検証レベル:
| ステップ種別 | 検証対象 | 例 |
|---|---|---|
| トリガー | Arrangeで再現 | API障害 -> mockResolvedValue({ ok: false }) |
| 処理 | 中間状態または呼び出し | 関数呼び出し、状態変更 |
| 観測可能な結果 | 最終出力の値 | 戻り値、エラーメッセージ、ログ出力 |
合格基準: 「観測可能な結果」がテスト対象の戻り値またはモックの呼び出し引数として検証されていれば合格
| スケルトンの状態 | 検証項目の決定方法 |
|---|---|
// Verification items:が列挙されている |
列挙された全項目をexpectで実装 |
// Verification items:がない |
Behavior記述の「観測可能な結果」から導出 |
| 両方ある | 検証項目を優先し、振る舞いは補足として使用 |
レビュー対象の主張に最初に合致する行を採用する:
| 条件 | 使用する境界 |
|---|---|
| 外部アダプター、query、migration、service契約自体がテスト対象 | 実境界、またはservice-integration-e2eレーンのservice-levelスタブ — モックは自身が代役を務める契約を証明できない |
| 外部APIまたはネットワーク呼び出しがテスト対象でない | モック |
| テスト対象のコンポーネント間連携 | 実物のin-processコンポーネント |
| 呼び出し自体がテストの検証対象(例: ログ出力) | 検証可能なモック(vi.fn()) |
| 呼び出しもその対象もテスト対象でない | 実物、または無視 |
fixture-e2e:
@dependency: full-ui (mocked backend))service-integration-e2e:
@dependency: full-system)| チェック | 不合格条件 |
|---|---|
| Property検証 | Property注釈があるのにfast-check未使用 |
| 振る舞い検証 | 「観測可能な結果」に対応するexpectがない |
| 検証項目網羅 | 列挙された検証項目がexpectに含まれていない |
| モック境界 | 統合テストで内部コンポーネントをモック化 |
| チェック | 不合格条件 |
|---|---|
| AAA構造 | Arrange/Act/Assertの区切りが不明確 |
| 独立性 | テスト間で状態共有、実行順序依存 |
| 再現性 | 日時・乱数に依存し結果が変動 |
複数の経路が同じmutationに到達する場合 — CLIの経路とHTTPハンドラ、スケジュールジョブと手動トリガー、バッチと単件エンドポイント — 4つの軸で比較する: 検証、分類、リソース上限、およびread / parse / mutation / reportingの順序。
差異を許可できるのは意図を決める出所のみ: 要件、Design Doc、ADR。テストはその判断の下流にある。存在する振る舞いを記録するものなので、許容側の経路をカバーする既存テストはそのbypassを許可するのではなく確認していることになる。差異が許可された後は、テストが決定どおりに振る舞うことを検証する。
許可する出所を持たない差異については、bypassを検出するテストを要求する。チェックをスキップする側の経路でmutationを実行し、そのスキップされたチェックが守っていた状態をアサートする。
| チェック | 不合格条件 |
|---|---|
| 検証の同等性 | 一方の経路が検証する入力を他方が未検証で受け入れており、その差異を許可する要件も契約もない |
| 分類の同等性 | 同じ失敗が経路によって異なる分類となり、呼び出し側が観測する内容が変わる |
| リソース上限の同等性 | 一方の経路がサイズ・件数・タイムアウトの上限を強制し、他方が省いている |
| 操作順序の同等性 | read / parse / mutation / reportingの順序が経路間で異なり、検証前にmutationしたり永続化前に報告したりしうる |
| bypassのカバレッジ | 説明のつかない差異について、許容側の経路でmutationを実行するテストがない |