エビデンス駆動テスト
動作の注釈付き証拠を記録し、PRや課題トラッカーに添付します。
録画は、あなたがコンピューター操作でアプリをテストしている様子をキャプチャしたものです。レコーダーを起動し、自分でアプリを操作(クリック、入力、ナビゲート)して各テスト対象を実行します。動画内のすべてのアクションは、テストがライブで実行されていることを示します。録画は、そのインタラクティブなセッションが表示されなければ証拠として価値がありません。ハーネスにコンピューター操作用ツールがないがGUIが存在する場合は、代わりに cua-driver でアプリを操作してください(下記参照)。それでもライブセッションであることに変わりはありません。
バンドルされているレコーダー scripts/evidence.py は、Linux、macOS、WindowsでFFmpegを使用してディスプレイをキャプチャし、テスト中に追加する各注釈にタイムスタンプを付け、停止時にそれらを動画に焼き付け、ffprobeで結果を検証します。セッションフォルダーに evidence.mp4、report.md、manifest.json を書き込みます。
入力
- テスト対象(必須): 検証する動作やフローを、テスト可能なステートメントで記述します。
- PR / 課題(オプション): エビデンスを投稿する場所。省略した場合は、リクエスターにのみ配信します。
レコーダー
EVIDENCE は、このスキルのフォルダー内にある scripts/evidence.py へのパスを示します(スキルがインストールされている場所、例: ~/.claude/skills/evidence-driven-testing/scripts/evidence.py)。必要なのはPython 3とFFmpegのみです。
-
事前確認:
python3 $EVIDENCE doctor—ffmpeg、ffprobe、libx264、assフィルター(ready)を確認し、次にこのマシンで動作する画面キャプチャソース(capture_readyとソースautoが選択します)を確認します。ツールチェーンがない場合のみ非ゼロで終了します。録画前にcapture_readyを確認してください。 -
プラットフォーム(
--source autoは利用可能な最初のものを選択):OS ソース 必要条件 Linux X11 / XWayland x11(x11grab)DISPLAYが設定されていることLinux Wayland wayland(wf-recorder)WAYLAND_DISPLAYが設定されていること、wf-recorderがPATHに存在すること、wlr-screencopyをサポートするコンポジター(既知のwlrootsベース: Sway、Hyprland、river、Wayfire、labwc、dwl、niri、またはwayland-infoで確認)が必要。GNOMEとKDE Waylandはこの方法ではキャプチャできません。doctorがその旨を伝えます。X11アプリの場合はXWayland経由でx11を使用するか、フォールバックレコーダーを使用します。--source waylandでも強制されますmacOS avfoundationターミナル/エージェントホストアプリに画面収録の許可が与えられていること。 doctorが--screen-index用の画面インデックスを一覧表示しますWindows gdigrab標準のffmpegビルド。プロセスチェック用に powershellデフォルトでは全画面をキャプチャします。
--geometry WxHと--offset X,Yで、x11、wayland、gdigrabで領域を切り抜きます。XWaylandはX11ウィンドウしか認識しないため、テスト対象のアプリがWaylandネイティブの場合はwaylandソースを優先してください。 -
クラッシュセーフな生キャプチャ: 生の録画はMPEG-TS(
raw.ts)であるため、レコーダーが強制終了されたりクラッシュしても、キャプチャされたものはプローブおよびレンダリング可能です。stopはそれを標準のevidence.mp4にリマックスまたは再エンコードします。 -
停止方法: Linuxでは、レコーダーはpidfdを介してシグナルを受け取ります。macOSとWindowsでは、
startがffmpeg子プロセスを所有する小さなスーパーバイザープロセスを起動し、stopは(セッションフォルダー内のstop.requestを介して)スーパーバイザーに中断、終了、強制終了を要求します。完了するとrecorder-exit.jsonを書き込みます。ベアPIDにシグナルを送ることは決してないため、リサイクルされたPIDにヒットすることはありません。レコーダーの実行中にスーパーバイザーが停止した場合、stopは拒否し、手動で停止するPIDを通知します。スーパーバイザーが、どのプロセスを開始したかを記録する前に停止した場合、stopは、自分で迷子のレコーダーを確認し、--accept-untracked-recorderを付けて再実行するまでブロックされたままになります。レポートにはその注意書きが記載されます。 -
フォールバックレコーダー(
doctorがキャプチャソースを報告しない場合、例: wf-recorderのないWayland):cua-driver recording start <dir>/stop(cua-driverセクションを参照)、またはOSのレコーダー(macOS:screencapture -v out.mov)。これらのパスでは注釈オーバーレイがないため、注釈プロトコルをファイルとして保持します。assertions.mdに各setup/test_start/assertionとその結果、およびおおよその動画タイムスタンプを、ヘッドレスパスとまったく同じようにリストします。 -
決して
--source test(合成パターンジェネレーター)をUIエビデンスとして提示しないでください。これはツールチェーンのスモークテスト用に存在します。リポジトリのtests/test_evidence.pyでテストされています。
手順
1. 画面を準備する
- ブラウザ/アプリのウィンドウを最大化します。ポップアップ、通知、余分なパネルを閉じます。
- セットアップ自体がテスト対象でない限り、録画前に開始状態(ログイン済み、正しいページ)に移動します。
- テスト対象の正確なリビジョンを記録します:
git rev-parse HEADとgit branch --show-current(またはデプロイURL)— レコーダーはこれらをレポートにスタンプします。
2. 録画を開始する
-
最初の意味のあるアクションの前に画面録画を開始します:
python3 $EVIDENCE start \ --output .artifacts/<task-name> \ --title "<検証内容>" \ --commit "$(git rev-parse HEAD)" --branch "$(git branch --show-current)" \ --environment "<OS / ブラウザ / ディスプレイ / デプロイ>"これにより、
sessionパスと選択されたsourceを含むJSONが出力されます。後続のすべてのコマンドのためにパスを保持します(SESSION=...)。ソースは自動検出され、画面全体がキャプチャされます。--source、--geometry、--offset、--display/--xauthority(X11)、--screen-index(macOS)、--output-name(Wayland)は、doctorや状況で必要な場合にのみ渡します。 -
開始コンテキストを説明する
setup注釈を追加します:python3 $EVIDENCE annotate "$SESSION" --type setup \ --message "ログイン済み、コネクターページに移動中"
3. コンピューター操作でテストし、その都度注釈を付ける
-
すべてのインタラクションをライブアプリでのコンピューター操作を通じて実行します。録画はあなたのセッションをキャプチャするため、テストとエビデンスは同じ行為です。見やすいペースで作業します。各アクションの後にUIが落ち着くまで待ち、状態変化が動画で確認できるようにします。
-
各名前付きテストの開始時に、Jestスタイルで
test_start注釈を追加します:python3 $EVIDENCE annotate "$SESSION" --type test_start \ --message "権限が'always'の場合、ツールを直接実行できるべき" -
各チェックの後に、
--result passed、failed、またはuntestedを指定してassertion注釈を追加します:python3 $EVIDENCE annotate "$SESSION" --type assertion --result passed \ --message "ツールが権限プロンプトなしで実行された" -
アサーションのルール:
- 意味のある状態変化ごとに1つのアサーション。統合し、UIラベルごとに注釈を付けないでください。
- "前提条件: ..." アサーションを使用して開始状態を確立します。
- 80文字未満、シグナル強度高(レコーダーは長いメッセージを拒否します)。
- テストを実行できない場合(前提条件不足、認証期限切れなど)、理由とともに
untestedとマークします。黙ってスキップしないでください。 - タイムスタンプは、アサートした時刻を記録し、その真偽は記録しません。
passedを選択する前に画面を確認してください。
4. 停止して確認する
-
最後のアサーションの後に録画を停止します:
python3 $EVIDENCE stop "$SESSION"これにより、キャプチャが停止され(正常に、レコーダーがフラッシュするように。要求を無視した場合のみエスカレーション)、注釈が
evidence.mp4に焼き付けられ、結果がプローブされ、その隣にreport.mdとmanifest.jsonが書き込まれます。成功時には"verified": trueを出力します。レンダリングに失敗した場合、セッションはfinalization_failedとマークされます。報告された原因を修正し、stopを再実行します(再試行ではレコーダーに2回シグナルを送りません)。レコーダープロセスに安全にシグナルを送れなくなった場合(プロセスが終了した、またはそのPIDが別のプロセスに属している場合)、セッションはrecorder_lostとマークされます。再度stopを実行すると、キャプチャされた動画がファイナライズされますが、それはレコーダープロセスが確実に終了した場合のみです。プロセスがまだ生きている場合は、先に停止してください。そうしないと、動画が書き込み中にレンダリングされる可能性があります。 -
共有する前に、録画が重要な瞬間を捉えていることを確認します。各アサーションのタイムスタンプでフレームを抽出し(
ffmpeg -ss <t> -i evidence.mp4 -frames:v 1 frame.png)、状態とラベルが表示されていることを確認します。 -
report.mdの注意事項セクションに記入します。プレースホルダーを残さないでください。
5. エビデンスを投稿する
report.mdがレポートです。テスト内容、環境と正確なコミット、テストごとの合格/不合格、注意事項。ゼロから書き直すのではなく、拡張してください。- 動画とサマリーをPRコメントとして投稿します(あなたのPRの場合はPR説明に埋め込みます)。
gh pr commentはローカル動画を添付できません。認証済みブラウザでPRのコメントボックスからevidence.mp4をアップロードするか、ホストにアップロードしてリンクします(例:before-and-afterアップロードアダプター)。コメントを再度開き、動画が再生されることを確認してから、投稿したと主張してください。 - 同じ動画を1行の結果とともに課題トラッカー(Linear/Jira)に添付します。
- レポートと録画をリクエスターに送信します。
ガードレール
- 動画は、実際のテストセッションがライブで駆動されている様子を示さなければなりません。スクリプト再生、編集されたクリップ、合成映像を録画として提示しないでください。ハーネスにコンピューター操作用ツールがないがGUIが存在する場合は、
cua-driverを介して駆動します。GUIがまったくない場合は、代わりにヘッドレスパスを使用します。 - 半分覆われた、またはタイル表示されたウィンドウを録画しないでください。最初に最大化します。
- 秘密、トークン、顧客データ、支払い情報が表示されている画面を録画しないでください。フローでそれらが必要な場合は、
untestedとマークし、理由を述べます。 - 修正を検証する場合は、新しい成功とともに古い失敗を表示または参照します。
- テスト対象の正確なコミット/ブランチ/デプロイを常に明記します。
コンピューター操作用ツールがない場合(GUIあり)
ディスプレイは存在するが、エージェントに組み込みのコンピューター操作機能がない場合は、cua-driver(macOS / Windows / Linux)をアクチュエーターとして使用します。それでもあなたがアプリをライブでテストしていることには変わりません。録画ルールは変更されません。入力メカニズムのみが異なります。
- 録画前に
cua-driver doctorでセットアップを確認します。cua-driverスキルがインストールされている場合は、それを読み、そのプロトコルに従います。アクション前のスナップショットの不変条件は必須です。 - インタラクションごとにループします:
launch_app→get_window_state(アクセシビリティツリー + スクリーンショット)→element_tokenで操作(click、type_text、press_key)→verify_stateで期待される事後条件を確認。各verify_stateチェックは、assertion注釈に1対1でマッピングされます。 doctorがcapture_ready: yesを報告する場合は、上記のバンドルレコーダーを動画と注釈に引き続き使用します。cua-driverは入力を提供するだけです。- それ以外の場合、
cua-driver recording start <output-dir>/cua-driver recording stopがレコーダーです(出力ディレクトリが必要で、デーモンが実行中である必要があります:cua-driver serve)。動画キャプチャはデフォルトでオンで、停止時に<output-dir>/recording.mp4にファイナライズされます。ただし、Windows/Linuxではffmpegをシェルアウトするため、ffmpegまたはディスプレイがない場合は、ターンごとの軌跡フォルダー(before/afterスクリーンショット、action.json、click.png)のみが生成され、動画はありません。停止後、recording.mp4が存在することを確認してから参照します。存在しない場合は、レコーダーを修正するか、ヘッドレスプロトコルに従って、ターンごとのbefore/afterスクリーンショットを番号付きキャプチャとして提示します。 - このパスで注釈オーバーレイが利用できない場合は、プロトコルをファイルとして保持します。
assertions.mdに各test_start/assertionとその結果を、ヘッドレスパスとまったく同じようにリストします。
ヘッドレスパス(GUIなし)
エージェントに録画可能なデスクトップがない場合は、同じアサーション規律を維持し、レコーダーをスクリプトキャプチャに置き換えます:
-
すべてを
.artifacts/<task-name>/に保存します(gitignoreしてください。エビデンスはアップロードされ、コミットされることはありません)。キャプチャスクリプトをキャプチャの横に置き、実行が再現可能になるようにします。 -
スクリーンショット:
before-and-afterCLI(@vercel/before-and-after)はURLまたは要素をキャプチャし、そのペアはPR埋め込みに直接フィードされます。Chromeが「使用可能なサンドボックスがありません」で失敗するコンテナ/VMでは、AGENT_BROWSER_ARGS="--no-sandbox"を設定します。 -
動画 / マルチステップフロー: 使い捨てのPlaywrightスクリプト。プロジェクトの依存関係にplaywrightを追加せずに実行します:
npx --yes --package=playwright node record.mjs(単なる
npx playwright node record.mjsは失敗します。nodeはPlaywright CLIコマンドではありません。--package=playwrightによってモジュールがパスに配置されます。)最小限のrecord.mjs:import { chromium } from "playwright"; const browser = await chromium.launch(); const context = await browser.newContext({ recordVideo: { dir: ".artifacts/<task-name>/" }, }); const page = await context.newPage(); await page.goto("http://localhost:3000/path-under-test"); // ...フローを駆動、ステップごとに意味のある状態変化を1つ... await context.close(); // .webmをファイナライズ await browser.close();ファイルが大きい場合は、ffmpegでトリミングまたは圧縮します。
-
注釈プロトコルはファイルになります: キャプチャをテスト順に番号付けし、アサーションを名前に含めます。
01-precondition-signed-in.png、02-it-saves-on-blur-passed.png。アーティファクトフォルダーにassertions.mdを保持し、各test_start/assertionとその結果(passed/failed/untested+ 理由)をリストします。
非UI変更にもエビデンスが必要
- API / パフォーマンス: 測定値を含むスクリプトプローブ。フェーズごとのリクエスト数、before/afterのレイテンシ。
probe-output.txtにキャプチャします。 - レンダリング / キャンバス / シェーダー: レンダリングフレームとピクセルアサーション(差分値)を目視で確認し、PNGとして保存します。
- エージェント動作: ツール呼び出しと応答を示す関連トランスクリプトの抜粋。
- バグ修正: 修正を書く前に失敗を再現してキャプチャします。そのキャプチャがbefore/afterペアの「before」部分です。
キャプチャの衛生管理
- プローブしているサーバーが あなたの コードを実行していることを確認します(正しいポート、正しいプロセス)。特に複数のエージェントがマシンを共有している場合:
lsof -i :<port>— またはlsofがインストールされていない場合: `ss -ltnp "spo