mcpField
A
agentic-tdd

agentic-tdd

github.com/reticlehqテスト・品質1.3k250 回インストール今日更新
リポジトリ

agentic-tdd について

実行中のアプリにレッド・グリーン・リファクターのTDDを適用するReticle向けスキルです。操作前に期待する結果を定義し、保存したフローを回帰確認に再利用します。

主な機能

  1. 01操作前に期待結果をアサート
  2. 02シグナル、状態、ネットワーク、要素を確認
  3. 03実装後に同じアサーションを再実行
  4. 04フローを保存して回帰テストに再利用

活用シーン

  1. 01機能実装前にテストを作成
  2. 02動作を保つリファクタリングの検証
  3. 03エンドツーエンドの操作を回帰確認に変換

MCP 対応

Reticleは、このスキルが使う操作、アサーション、記録、検証のツールをMCP経由で提供します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/reticlehq/reticle --skill agentic-tdd

インストール後、Claude Code で/agentic-tddを入力して読み込まれたか確認します。

詳細

赤・緑・リファクタリング:実行中のアプリに対して

ユニットテストはユニットを動かします。「Deploy をクリックすると /api/deploy に POST し、ストアが deploying に移行して、バナーが表示される」とは言えません。その結果が現れるのは、アプリ全体を実行したときだけだからです。そのため、興味深いバグが潜むまさにその地点でループが止まり、エージェントはコードを書いて期待するしかなくなります。

これは Reticle を使って実際のアプリを動かし、同じ手順を一段上のレベルで実行します。まだセットアップしていない場合は、reticle スキルに従ってください。Reticle をインストールし、init によるアプリのファイル変更前にユーザーに確認し、1 つのフローを実証します。

なぜこれは単なる事後テストではなく TDD なのか

テストファーストの価値は、まだ答えがわからないうちにオラクルを書くことにあります。結果を見たあとに書かれた期待値は、起きたことに合わせていつでも調整できます。エージェントは特に、その調整が得意です。今書いたコードが正しいといえるような出力の解釈を見つけてしまいます。

reticle_act_and_wait({ ref, action, until }) は順序を構造的に強制します。until はアクションの引数なので、その結果はアクションの実行前に明示されます。これは偽装できない形で実現した赤・緑のループです。

1. RED:期待値を書き、失敗を確認する

機能を書く前に、アプリが何をしなければならないかを明示します。

reticle_act_and_wait({ sessionId, ref, action: "click", until: { kind: "allOf", predicates: [
  { kind: "net",     method: "POST", urlContains: "/api/deploy", status: 200 },
  { kind: "signal",  name: "deploy:started" },
  { kind: "element", query: { testid: "deploy-banner" } },
  { kind: "console", level: "error", absent: true },
]}})

ここでは verified: "no" を期待します。確認していない赤は、信頼できないテストです。 何も書いていないのに yes が返ってきた場合、その期待値は変更内容に対して具体性が足りません。適切な理由で失敗するまで、条件を絞り込んでください。

verified: "unknown" は赤ではありません。Reticle が判定できなかったという意味なので、ループからシグナルがまったく得られません。コードを書く前にこれを解決してください。通常は、アプリが実際に生み出せる結果を指定します。

2. GREEN:同じ呼び出しがパスするまで実装する

条件を満たす最小限の変更を行い、その後、まったく変更せずに同じ呼び出しを再実行します。最後の言葉が重要です。作成したものに合わせて述語を編集すると、TDD は語りに変わってしまいます。アサーションを変更する必要がある場合は、元の期待値が誤っていた理由を声に出して説明してください。

判定が unknown / unsettled だった場合は、再度動作させるより、もう一度アサーションを実行するほうが望ましいです:reticle_assert({ predicate, since, timeout_ms: 8000 })。再実行すると、すでに発生した副作用が繰り返されます。

3. REFACTOR:期待値がセーフティネットになる

ここからは実装を自由に変更し、再実行します。述語はマークアップではなく動作(リクエスト、シグナル、状態のパス)に結び付いているため、動作を維持するリファクタリングなら引き続き成功します。一方、DOM の形状に依存するテストは、理由もなく失敗します。

4. 次の変更でもループを続ける

テストファーストで書く価値のあるジャーニーは、何度でも再実行する価値があります。一度保存しておきましょう:

reticle_run({ tool: "reticle_record", sessionId, args: { action: "start", name: "deploy" } })
// drive the journey with reticle_act_and_wait, as in step 1
reticle_run({ tool: "reticle_record", sessionId, args: { action: "stop", name: "deploy" } })
reticle_run({ tool: "reticle_flow_save", sessionId, args: { flowName: "deploy" } })
reticle_run({ tool: "reticle_verify", sessionId, args: { action: "flows" } })   // every saved flow, no model per flow

これにより、赤・緑のループが手書き不要のリグレッションテストスイートになります。

何をアサートするか:強い順

  1. アプリが自ら発するシグナル({ kind: "signal" }):アプリ自身の語彙で成功を宣言します。利用可能な中で最も強い方法です。
  2. 状態(reticle_look { action: "state" }):アプリが認識している状態です。ストアが変わらないまま UI だけが変化した場合に検出できます。
  3. ネットワーク:リクエスト、メソッド、ステータスです。実際のものの代わりにモックが使われている場合に検出できます。
  4. 要素の表示:必要ですが、これだけでは不十分です。何でもレンダリングできます。
  5. コンソールエラーがないこと:常に含めますが、これだけに頼ってはいけません。不在だけを条件とする述語は、何にも接続されていないコントロールでもパスします。

誠実さ

判定を緑にするために、チェックを決して弱めないでください。 このループにおいて、それは些細な過ちではありません。ループを逆向きに回すことになり、動作しない機能を対象とした緑のテストスイートができあがります。


述語のリファレンス:curl https://docs.reticle.sh/predicates.md。その他すべて:curl https://docs.reticle.sh/llms.txt。

コメント