evidence-driven-testing について
テスト証跡を記録して提出するためのスキルです。変更内容に応じて、UI のライブ録画、スクリプトによるキャプチャ、CLI/API の出力比較を案内します。
主な機能
- 01変更に応じた証跡選択
- 02注釈付きライブ画面録画
- 03クロスプラットフォーム録画ツール
- 04ヘッドレスキャプチャの手順
- 05レポートとマニフェスト生成
活用シーン
- 01UI テスト結果の記録
- 02CLI や API の変更確認
- 03ドキュメントと実行可能な例の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ michaelshimeles/ rstack --skill evidence-driven-testingインストール後、Claude Code で/evidence-driven-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
scripts/run-playwright.shevidence.pyscripts/playwright/package.jsonpackage-lock.json詳細
エビデンスに基づくテスト
動作の証拠を記録し、指定された宛先に提出します。
変更内容に見合ったエビデンスを選びます。インタラクティブなフローにはレコーダーを、ヘッドレス UI のチェックにはスクリプトによるキャプチャを、CLI や API の変更には出力のペアを使用します。ドキュメントのみの編集では、コンテンツのチェックと実行可能な例の検証が必要であり、録画は不要です。タスクですでに取得済みの適切なエビデンスは再利用します。依頼された作業に含まれる宛先にのみ公開します。
録画とは、コンピューターを操作してアプリをテストする様子を記録したものです。レコーダーを起動し、各テスト対象について、クリック、入力、画面遷移などを行って、自分でアプリを操作します。動画内のすべての操作が、その場で実施しているテストです。インタラクティブな操作セッションが映っていなければ、録画はエビデンスとして価値がありません。ハーネスにコンピューター操作ツールがないものの GUI がある場合は、代わりに cua-driver を使ってアプリを操作します(以下を参照)。これも、その場で実施するセッションです。
同梱されているレコーダー scripts/evidence.py は、Linux、macOS、Windows で FFmpeg を使って画面をキャプチャし、テスト中に追加した各注釈にタイムスタンプを付け、停止時に注釈を動画に焼き込み、ffprobe で結果を検証します。セッションフォルダーに evidence.mp4、report.md、manifest.json を出力します。
入力
- テスト対象(必須):検証する動作やフローを、テスト可能な文として記述します。
- PR/issue(任意):エビデンスの投稿先です。省略した場合、依頼者にのみ提出します。
レコーダー
以下の 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が選択するソース)を調べます。終了コードが 0 以外になるのは、ツールチェーンが不足している場合だけです。録画前に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、またカーネルや seccomp ポリシーによって pidfd が拒否された Linux では、
startが小さなスーパーバイザープロセスを起動し、そのプロセスが ffmpeg 子プロセスを管理します。stopはセッションフォルダー内のstop.requestを介して中断、終了、強制終了の順に要求し、完了時にrecorder-exit.jsonを書き込みます。PID を直接シグナルすることはないため、再利用された PID に誤ってシグナルが送られることはありません。レコーダーの実行中にスーパーバイザーが終了した場合、stopは停止を拒否し、手動で停止する PID を伝えます。開始したプロセスを記録する前にスーパーバイザーが終了した場合、残存するレコーダーがないことを自分で確認し、--accept-untracked-recorderを付けて再実行するまで、stopはブロックされたままです。その場合、レポートにはその注意事項が記載されます。 -
doctorがキャプチャーソースなしと報告した場合の代替レコーダー(例:wf-recorder がない Wayland):cua-driver recording start <dir>/stop(cua-driver のセクションを参照)、または OS のレコーダー(macOS:screencapture -v out.mov)を使用します。これらの方法では注釈オーバーレイがないため、ヘッドレスの場合と同様に、各setup/test_start/assertionとその結果、およびおおよその動画タイムスタンプを記載したassertions.mdを作成し、注釈プロトコルをファイルとして保持してください。 -
絶対に
--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 "<what is being verified>" \ --commit "$(git rev-parse HEAD)" --branch "$(git branch --show-current)" \ --environment "<OS / browser / display / deployment>"sessionのパスと選択されたsourceを含む JSON が出力されます。後続のすべてのコマンドで使うパス(SESSION=...)を控えておいてください。ソースは自動検出され、画面全体がキャプチャされます。doctorの結果や状況に応じて必要な場合にのみ、--source、--geometry、--offset、--display/--xauthority(X11)、--screen-index(macOS)、または--output-name(Wayland)を渡してください。 -
開始時の状況を説明する
setupアノテーションを追加します。python3 $EVIDENCE annotate "$SESSION" --type setup \ --message "Logged in, navigating to connectors page"
3. 操作しながらアノテーションを付けてテストする
-
実行中のアプリは、コンピューター操作を通じてのみ操作します。セッションが録画されるため、テストと証拠の記録は同じ作業です。画面上で確認しやすいペースで進め、各操作の後は UI が落ち着くまで待って、状態の変化が動画で見えるようにしてください。
-
名前付きの各テストの開始時に、Jest スタイルの
test_startアノテーションを追加します。python3 $EVIDENCE annotate "$SESSION" --type test_start \ --message "It should execute the tool directly when permission is 'always'" -
各確認後に、
--result passed、failed、またはuntestedを指定したassertionアノテーションを追加します。python3 $EVIDENCE annotate "$SESSION" --type assertion --result passed \ --message "Tool ran without a permission prompt" -
アサーションのルール:
- 意味のある状態変化ごとにアサーションを1つ付けます。UI のラベルごとではなく、まとめて記録してください。
- 開始状態を明示するには、「Precondition: ...」というアサーションを使います。
- 80文字未満で、重要な情報に絞ってください(レコーダーは長すぎるメッセージを拒否します)。
- 前提条件が不足している、認証の有効期間が切れているなどの理由でテストを実行できない場合は、理由を添えて
untestedとします。黙ってスキップしないでください。 - タイムスタンプはアサーションを記録した時刻を示すものであり、それが正しかったかどうかを示すものではありません。
passedを選ぶ前に画面を確認してください。
4. 録画を停止して確認する
-
最後のアサーションを記録した後、録画を停止します。
python3 $EVIDENCE stop "$SESSION"これによりキャプチャが停止します(レコーダーがバッファーをフラッシュできるよう、正常に停止します。要求に応答しない場合に限り、より強い手段で停止します)。アノテーションを
evidence.mp4に書き込み、結果を検査して、同じ場所にreport.mdとmanifest.jsonを作成します。成功すると"verified": trueと出力されます。レンダリングに失敗した場合、セッションはfinalization_failedとして記録されます。報告された原因を修正してから、もう一度stopを実行してください(再試行によってレコーダーに停止シグナルが二度送られることはありません)。レコーダーのプロセスに安全にシグナルを送れなくなった場合(プロセスが終了した、またはその PID が別のプロセスに使われている場合)、セッションはrecorder_lostとして記録されます。もう一度stopを実行すると、キャプチャ済みの動画を確定できますが、レコーダーのプロセスが終了したことを確認してからにしてください。まだ動作中の場合は、先に停止してください。そうしないと、書き込み中の動画がレンダリングされてしまいます。 -
共有する前に、録画に重要な場面が含まれていることを確認します。各アサーションのタイムスタンプでフレームを抽出し(
ffmpeg -ss <t> -i evidence.mp4 -frames:v 1 frame.png)、状態とラベルが見えることを確認してください。 -
report.mdの「Caveats」セクションを記入します。プレースホルダーのままにしないでください。
5. 証拠を投稿する
report.mdがレポートです。テスト内容、環境と正確なコミット、テストごとの合否、注意事項を記載します。最初から書き直すのではなく、既存の内容を拡充してください。- 動画と概要を PR のコメントとして投稿します(自分の PR の場合は、PR の説明に埋め込んでください)。
gh pr commentではローカル動画を添付できません。認証済みのブラウザーで PR のコメント欄からevidence.mp4をアップロードするか、ホストにアップロードしてリンクを共有してください(例:before-and-afterアップロードアダプター)。投稿したと伝える前に、コメントを開き直して動画が再生されることを確認してください。 - タスクにトラッカーのイシューが含まれ、そこへの投稿が許可されている場合は、同じ動画を添付し、結果を一行で記載してください。
- レポートと録画を依頼者に送付します。
ガードレール
- 動画には、テストセッションを実際にライブで操作している様子を映す必要があります。スクリプトによる再生、編集でつなぎ合わせたクリップ、合成映像を録画として提示してはいけません。ハーネスにコンピューター操作ツールがなくてもGUIがある場合は、
cua-driverを使って操作してください。GUIがまったくない場合は、ヘッドレス方式を使用してください。 - 半分隠れたウィンドウやタイル表示されたウィンドウを録画してはいけません。録画前に最大化してください。
- シークレット、トークン、顧客データ、支払い情報が表示された画面を録画してはいけません。フローでそれらが必要な場合は、
untestedと記し、その理由を説明してください。 - 修正を検証する際は、以前の失敗を新しい成功と並べて表示するか、参照してください。
- テスト対象のコミット、ブランチ、デプロイ環境を必ず正確に明記してください。
コンピューター操作ツールがない場合:cua-driverで操作する(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の確認は、1対1でassertionアノテーションに対応します。 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またはディスプレイがない場合は、ターンごとの軌跡フォルダー(操作前後のスクリーンショット、action.json、click.png)のみが生成され、動画は生成されません。停止後、引用する前にrecording.mp4が存在することを確認してください。ファイルが存在しない場合は、レコーダーを修正するか、ヘッドレス方式の手順に従って、ターンごとの操作前後のスクリーンショットを番号付きキャプチャとして提示してください。 - この方法でアノテーションオーバーレイを利用できない場合は、手順をファイルとして記録してください。ヘッドレス方式とまったく同じ形式で、各
test_start/assertionとその結果を列挙したassertions.mdを作成してください。
ヘッドレス環境での手順(GUI が利用できない場合)
エージェントが記録用のデスクトップを使えない場合も、同じ検証規律を守ってください。 レコーダーをスクリプトによるキャプチャに置き換えます。
-
すべてを
.artifacts/<task-name>/に保存します(gitignore に追加してください。エビデンスはアップロードし、コミットしません)。実行を再現できるよう、キャプチャ用スクリプトもキャプチャと同じ場所に保存します。 -
スクリーンショット:
before-and-afterCLI(@vercel/before-and-after)で URL または要素をキャプチャでき、そのペアを PR の埋め込みに直接使用できます。Chrome が「No usable sandbox」エラーで失敗するコンテナーや VM では、AGENT_BROWSER_ARGS="--no-sandbox"を設定します。 -
動画/複数ステップのフロー:Playwright をプロジェクトの依存関係に追加せず、単発の Playwright スクリプトを実行します。
bash /path/to/evidence-driven-testing/scripts/run-playwright.sh record.mjsこのヘルパーは、同梱のマニフェストとロックファイルを使い、一時ディレクトリで
npm ciを実行して、固定バージョンの Playwright をインストールします。スクリプトをそのインストール先の隣にコピーし、必要に応じて Chromium をインストールして、終了時に一時ディレクトリを削除します。呼び出し元の作業ディレクトリを保持するため、相対パスで指定したアーティファクトは引き続きプロジェクト内を指します。Node 20+ と npm が必要です。ブラウザーのキャッシュは後続の実行でも利用できます。スクリプトは自己完結型にしてください。相対インポートや隣接するデータファイルはコピーされません。ローカルインポートを使うスクリプトには、プロジェクト既存の Playwright セットアップを使用してください。キャプチャツールをアップグレードする際は、scripts/playwright/package.jsonを更新し、npm でロックファイルを再生成して、キャプチャチェックを再実行してください。npx --package=playwrightは実行ファイルを PATH に追加しますが、任意の ESM スクリプトからパッケージをインポート可能にするものではありません。最小限のrecord.mjsの例:import { chromium } from "playwright"; const browser = await chromium.launch(); try { const context = await browser.newContext({ recordVideo: { dir: ".artifacts/<task-name>/" }, }); try { const page = await context.newPage(); await page.goto("http://localhost:3000/path-under-test"); // Drive the flow and check each expected state here. } finally { await context.close(); // Finalizes the video even if an assertion fails. } } finally { 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/パフォーマンス:計測値を含むスクリプトによるプローブを実行し、フェーズごとのリクエスト数や変更前後のレイテンシを
probe-output.txtに記録します。 - レンダリング/キャンバス/シェーダー:レンダリングしたフレームとピクセルアサーション(差分値)を取得し、目視で確認して PNG として保存します。
- エージェントの動作:ツール呼び出しと応答を示す、該当するトランスクリプトの抜粋を用意します。
- バグ修正:修正を書く前に、失敗を再現してキャプチャします。このキャプチャが変更前後のペアの「変更前」側になります。
キャプチャの衛生管理
- プローブ対象のサーバーが自分のコードを実行していることを確認します(正しいポート、正しいプロセス)。複数のエージェントが同じマシンを共有している場合は特に重要です。
lsof -i :<port>を使用するか、lsofがインストールされていない環境では、ss -ltnp "sport = :<port>"でリスナーの PID を確認し、続けてps -p <pid> -o args=で自分のプロセスかどうかを確認します。 - エビデンスはリポジトリのチェック(型チェック/ビルド/テスト)を補完するものであり、それらに取って代わるものではありません。
- PR の埋め込みには、変更前後のメディアペアを変更前後ツールに渡します(例:
before-and-after before.png after.png --markdown)。