Test Results
エージェントのテスト実行を進行中のまま表示します。テストはそれぞれのファイルに流れ込み、終わると「118 passed, 2 failed in 4.2s」に折りたたまれ、失敗はすべて開いたまま残ります。単語単位の Expected と Received の差分、タイムアウトとスナップショット、Stack Trace によるスタック、フィルター、失敗したテストの再実行と修正の依頼、さらに Vitest、Jest、Playwright、pytest 用のアダプターを備えます。
エージェントがテストを実行するとき、チャットには開発者が知りたいことを表示するべきです。どこまで進んだか、何が失敗したか、そしてなぜか。実行中、Test Results は「Running tests · 42 of 120」というライブの行を表示し、件数は桁ごとに進み、バーは成功・失敗・スキップに分かれます。テストは終わるたびにファイルへ流れ込み、実行中のファイルは開いたままです。
実行が終わると、行は「118 passed, 2 failed in 4.2s」のような過去形のサマリーに変わります。問題のない実行は折りたたまれます。失敗した実行は開いたままで、成功したファイルは折りたたまれ、失敗したファイルは開いたままです。ただし自分で開閉した場合はそれに従います。各失敗にはメッセージ、単語単位の Expected と Received の diff、そして Stack Trace によるスタックが表示され、自分のフレームが先に、フレームワークのフレームは折りたたまれます。タイムアウトとスナップショットの不一致には専用の表現があります。
All、Failed、Skipped、Slow で絞り込み、失敗をテキストでコピーし、フレームをエディターで開き、Ask to fix、Rerun failed、Rerun、Update snapshot をエージェントに返せます。fromVitestJson、fromJestJson、fromPlaywrightJson、fromJUnitXml はレポートを実行に変換し、applyTestEvent はライブイベントを一つの実行にまとめます。
AI SDKと使う
runTests を、レポーターのイベントごとに実行を返す execute を持つツールにすると、更新がそれぞれ暫定出力として届きます。テストが失敗したら開いたままになる ToolCall の中に表示し、Ask to fix と Rerun failed をメッセージとしてエージェントに返します。
保存したレポートから
fromVitestJson と fromJestJson は JSON レポーターの出力を読み込みます。root を渡すと絶対パスを短くでき、getEditorHref を渡すとフレームを Cursor や VS Code で開けます。
pytest と JUnit XML
fromJUnitXml は pytest --junitxml などの JUnit レポートを読み込みます。テストクラスは describe ブロックになり、失敗したソースはコードとして表示され、Rerun failed にはノード ID が渡されます。
独自のイベントから
任意のランナーから run-start、test-start、test-end、file-end、run-end のイベントを送り、applyTestEvent でまとめます。純粋関数なので、reducer、ストア、サーバーのどこでも動きます。
構造
外側から内側へ組み合わせるパーツ。
| パーツ | 説明 |
|---|---|
TestResults | 実行:ライブのヘッダー、進捗、フィルター、アクション、ファイル。 |
ValueDiff | 変わった単語に印を付けた Expected と Received。 |
applyTestEvent, createTestRun | ストリーミングされたイベントから実行を組み立てる純粋なヘルパー。 |
fromVitestJson, fromJestJson, fromPlaywrightJson, fromJUnitXml | レポーターの出力を実行に変換するアダプター。 |
summarizeRun, formatFailures | サマリーの一行と、プロンプトやクリップボード向けのプレーンテキストの失敗。 |
TestResults
children 以外のすべての section の props も受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
runアダプター、applyTestEvent、または独自データからの実行。 | TestRun | – |
titleテスト実行中のライブラベル。 | string | "Running tests" |
labelリージョンのアクセシブルな名前。 | string | "Test results" |
slowThresholdこのミリ秒以上かかったテストを遅いテストとして扱います。 | number | 300 |
rootスタック内のパスから取り除くプロジェクトのルート。 | string | – |
defaultOpen実行を開くかどうかを上書きします。既定では実行中と何かが失敗したときに開いたままになります。 | boolean | – |
defaultFilter最初に選ばれているフィルター。 | "all" | "failed" | "skipped" | "slow" | "all" |
onAskToFix実行と各失敗に Ask to fix を表示します。 | (failed: FailedTest[]) => void | – |
onRerunFailed実行が失敗ありで終わったら Rerun failed を表示します。 | (failed: FailedTest[]) => void | – |
onRerunTest各失敗に Rerun を表示します。 | (failed: FailedTest) => void | – |
onUpdateSnapshotスナップショットの不一致に Update snapshot を表示します。 | (failed: FailedTest) => void | – |
getFrameHrefスタックフレームをリンクに変えます。例えば getEditorHref を使います。 | (frame: StackFrame) => string | undefined | – |
onFrameClickフレームがクリックされたときに呼ばれます。 | (frame: StackFrame, event: MouseEvent) => void | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
statusテストがまだ実行中かどうか。 | "running" | "done" | "cancelled" | – |
files開始した順のファイル。それぞれにテスト、所要時間、読み込めなかった場合はエラーが含まれます。 | TestFile[] | – |
total「42 of 120」のための予定テスト数。省略時はファイルごとに集めた件数です。 | number | – |
durationサマリー用のミリ秒。省略すると実行中に計測します。 | number | – |
startedAtライブタイマー用の、実行が始まった時刻のタイムスタンプ。 | number | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
nameテスト自身の名前。 | string | – |
suite外側から順に並んだ、囲んでいる describe ブロック。 | string[] | – |
statusテストの状態。 | "queued" | "running" | "passed" | "failed" | "skipped" | "todo" | – |
durationミリ秒。 | number | – |
retries再試行された回数。 | number | – |
failure失敗した理由。 | TestFailure | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
kind「Timed out after 5s」や「Snapshot mismatch」などの表現を選びます。 | "assertion" | "snapshot" | "timeout" | "error" | – |
messageExpected と Received の行を除いたアサーションのメッセージ。 | string | – |
expected, received比較の両側。エラー、diff、またはメッセージから読み取ります。 | string | – |
stackparseStackTrace に渡すテキスト。フレームがないときは省略されます。 | string | – |
detailspytest の失敗したソースなどの追加出力。 | string | – |
rawCopy が使う元のテキスト。 | string | – |
applyTestEvent(run, event)
新しい実行を返します。createTestRun() は最初に使う空の実行を返します。
| プロパティ | 型 | デフォルト |
|---|---|---|
eventrun-start、file-start、test-start、test-end、file-end、run-end のいずれか。テストは id、またはファイル・スイート・名前で照合されます。 | TestEvent | – |
event.error文字列、または Vitest の TestError のように message、stack、expected、actual、diff を持つオブジェクト。 | TestErrorInput | – |
fromVitestJson(report, options)
fromJestJson も同じレポートを受け取ります。fromPlaywrightJson は Playwright の JSON レポーターを、fromJUnitXml(xml, options) は JUnit XML を読み込みます。
| プロパティ | 型 | デフォルト |
|---|---|---|
options.rootファイルパスから取り除くプロジェクトのルート。省略すると、パスは src や tests などの最初のフォルダーから始まります。 | string | – |
| キー | アクション |
|---|---|
| Tab | 実行のヘッダー、フィルター、アクション、各ファイル、各失敗テストを順に移動します。 |
| EnterSpace | 実行、ファイル、または失敗を開閉します。 |
| ←→ | フィルター間を移動します。 |
- 実行はテスト中に aria-busy を持つ名前付きリージョンです。丁寧なライブリージョンが最終サマリーを一度だけ読み上げるので、流れ込むテストや増えていく件数は静かなままです。
- 実行のヘッダー、各ファイル、各失敗テストは aria-expanded を持つ開閉ボタンです。名前はサマリー、ファイルの件数、またはテストの状態と名前を読み上げます。
- フィルターはトグルグループです。矢印キーで選択肢を移動でき、該当がないフィルターは無効になります。
- 状態を色だけで示すことはありません。状態ごとに専用のマークがあり、スクリーンリーダーは各テストの前に「Passed」または「Failed」を読み上げ、Expected と Received にはラベルがあり、変わった単語は強制カラーで下線が付きます。視差効果を減らす設定では、行とマークはスライドせずに表示されます。
使用技術
Test Results を構成する無料のHextaUIコンポーネントです。それぞれ単独でインストールできます。
コード
7 個のファイルを components/blocks/test-results に追加しました。