AIエージェントで実践するテスト駆動開発 (Claude 4 × Cursor編)


こんにちは、 Gaji-Labo フロントエンドエンジニアの石垣 (@semigura) です。

AIエージェントを利用した開発手法がますます盛り上がっているこの頃ですが、Gaji-Labo でも引き続きスタートアップ支援をはじめとして、日々の開発にAIをどう活かすかの検証が行われています。

当記事ではAIを使ったワークフローのひとつとして、「AIによるテスト駆動開発」を実践してみましたので検証結果をまとめてみます。AIエージェントと対話しながらTDDの Red/Green/Refactor サイクルの一連を回してみました。

今回の検証環境は Cursor + Claude 4 Sonnet です。モデルにより実行結果は異なること、また当記事の内容について、同じプロンプトでも完全には再現性が保証されないことをご留意ください。

0. AIによるテスト検証環境(Todoアプリ)の構築

まずは本題に入る前に、AIに基本的な Todo アプリの作成を依頼しました。

今回は React + TypeScript で Todo アプリを作り、Vitest でテストする環境を作ります。

React + TypeScript + Vitestの環境を構築し、基本的なTodoアプリとその動作を保証する包括的なテストを作成してください。

このプロンプトにより、アプリとそれに付随する17個のテストケースが生成されました。

代表的なテストケース例は以下です。

test('新しいタスクを追加できる', async () => {
  const user = userEvent.setup()
  render(<TodoApp />)
  
  const input = screen.getByPlaceholderText('新しいタスクを入力...')
  const addButton = screen.getByText('追加')
  
  await user.type(input, '新しいタスク')
  await user.click(addButton)
  
  expect(screen.getByText('新しいタスク')).toBeInTheDocument()
  expect(screen.getByText('総タスク数: 1')).toBeInTheDocument()
  expect(screen.getByText('未完了: 1')).toBeInTheDocument()
})
AIが生成したシンプルなTodoアプリ

Vitest を実行すると、すべてのテストケースが合格しました。

✓ TodoApp 基本機能 (3個)
  ✓ TodoAppが正しくレンダリングされる
  ✓ 初期状態では空の統計が表示される  
  ✓ 初期タスクが渡された場合に表示される

✓ タスク追加機能 (5個)
  ✓ 新しいタスクを追加できる
  ✓ Enterキーでタスクを追加できる
  ✓ 空文字のタスクは追加されない
  ✓ タスク追加後、入力フィールドがクリアされる
  ✓ 複数のタスクを追加できる

✓ タスク削除機能 (3個)
  ✓ タスクを削除できる
  ✓ 複数タスクから特定のタスクを削除できる
  ✓ 完了済みタスクも削除できる

✓ タスク完了切り替え機能 (3個)
  ✓ 未完了タスクをクリックして完了にできる
  ✓ 完了タスクをクリックして未完了にできる
  ✓ 複数タスクで個別に完了状態を切り替えられる

✓ 統計表示機能 (3個)
  ✓ 混在したタスクで正しい統計が表示される
  ✓ タスク追加・削除・完了切り替え時に統計が動的に更新される
  ✓ 全て完了した場合の統計表示

Test Files  1 passed (1)
Tests  17 passed (17)
Duration  4.20s

これで検証環境は準備できました。ここからが本題のTDD実践です。

1. 新規機能の要件インプットとテスト追加(Red フェーズ)

今回は「作成から90日以上経過したタスクを赤字で表示する」という機能を追加してみます。
まずはAIに、この機能要件を満たすテストを書いてもらいます。

「タスク作成時からの経過日数が90日以上の場合は赤字にする」
この要件に対するテストを生成してください。
実装はせずにテスト生成のみを行ってください。

シンプルなプロンプトですが、この指示でAIはエッジケースを含む13個のテストケースを生成しました。

  • 90日経過タスクの赤字表示機能
    • 90日未満のタスクは通常表示される
    • 90日ちょうどのタスクは通常表示される
    • 91日以上経過したタスクは赤字で表示される
    • 120日経過したタスクも赤字で表示される
    • 完了済みタスクでも90日経過していれば赤字表示される
    • 複数タスクでそれぞれ正しく表示される
    • 新しく追加したタスクは通常表示される
    • うるう年をまたいだ日付計算が正しく動作する
  • 統計画面での期限切れタスク表示
    • 期限切れタスクがない場合は0件と表示される
    • 期限切れタスクが1件の場合
    • 期限切れタスクが複数件の場合
    • 完了済み期限切れタスクはカウントされない
    • タスク操作後に期限切れ統計が更新される

テストを実行すると、期待通り途中で失敗します。これで Red フェーズは完遂しました。

所感

期待通りの結果になりましたが、これはアプリが非常に簡単な構成だからこその結果かなとも感じます。実際はプロジェクトのコンテキストを読み込ませつつ、人間とAI双方がレビューを繰り返してテストケースを構築していくことになるかと思います。

今回の検証での所要時間は5分足らずほどでしたが、アプリの構成と追加機能の要件が複雑になるにつれ往復回数と時間が膨れ上がる可能性があります。そのためにもコンテキストのインプットと Rules などでの効率化が重要です。

今回は非常にシンプルな要件のためプロンプト内に含めましたが、実際の開発では GitHub MCP などを通じて issue や仕様書から要件を理解させるとスムーズになるかと思います。

2. 最小限の実装(Green フェーズ)

次に、Red フェーズで追加したテストを合格させるための実装をAIに依頼します。

テストを実行し、結果から実装を行ってください。

何度かAIがテスト実行を繰り返しながら実装を進めます。
10分ほどの後にRed フェーズで追加したすべてのテストが合格する実装が完了しました。

所感

Green フェーズの実行は今回10分足らずほどでしたが、これもテストケースの複雑さにより時間が左右される想定です。

また、非常にありがちな出力として「TypeScript の型エラーを対応しない」「型エラーを対応するが any を用いる」などコーディングルールを理解しないまま実装に移るケースがあるので、これもまたコンテキストをしっかりインプットさせた上で実行フェーズに移ってもらう必要があります。

Red フェーズでなるべく細かい粒度でテストを生成させること、可能であれば他機能のコンテキストから分離したテストにすること、実装も細かい単位で行ってもらうことが最適化の鍵になります。

そのためにはコンポーネントが疎結合であったりコードが単一責務の原則を守って実装されていること、そして指示者がプロジェクトの設計思想を理解していることが重要かなと思います。

3. リファクタリングを行う (Refactor フェーズ)

コード洗練のために Refactor フェーズを実行します。

現在のコードを確認し、保守性・可読性・パフォーマンスを向上させるためのリファクタリングを実行してください。

この指示により、AIはコンポーネントのロジックをカスタムフックに分離するなどの複数の改善を行いました。

AIが生成したリファクタリング内容の図解

もちろんリファクタリング後もすべてのテストは成功を維持しています。

これでAIによるTDDの1サイクルが完了しました。

所感

今回はシンプルなプロンプトですが、実際のケースではプロジェクトによって重視する観点を含めることになります。例えばアクセシビリティ重視やSEO対策など。

Refactor フェーズまで進むと追加される機能に関しての理解がスレッドに蓄積されていますので、前2回よりは所要時間が抑えられるかと思います。

AIによるTDD開発のメリット・デメリット

メリット

要件の明確化

これはAIを用いないTDDでも同じくですが、テストコードが動く仕様書となるので実装すべき内容が具体的になります。加えてAIを使うことで人間が見落としたり忘れたりする要件も漏れずに実装できる可能性が高まります。

網羅的なテスト作成

人間が作成するテストケースは漏れが存在する場合が往々にしてあります。AIに要件を理解させテストを生成してもらうことで人間が網羅しきれないテストケースをカバーできます。
それを人間がレビューすることで更にテストケースの精度が高まります。

デメリット

とにかくコンテキスト依存

TDDに限らずAIでの開発はどれだけコンテキストを理解してもらっているかに依存するのを強く感じます。Cursor であればプロジェクトのコードを蓄積させ、 Rules を駆使することでなるべく他のコードと齟齬ない実装に近づけられます。
あるいはコンテキストがなるべく不要になるような実装をさせるのも手です。作業を細かい粒度で切り分け、他の作業や実装から切り離して対応できるようにすると良いかと感じました。これはAIでなく人間のみの開発でも効率化において同じことが言えるかと思います。

AI生成物の検証

前提として、AIの出力物はプロンプトを入力した人間が最終責任を持つべきです。しっかりとコードを検証・レビューし、AIに完全に依存するのではなくより高い成果を出すための補助としてAIを用いるという観点を持っておくのが重要です。

まとめ

今回はAIによるTDD開発について検証してみました。

当記事の検証では非常にシンプルな構成でのTDD開発実践に留まりましたが、このような構成であれば単純なプロンプトでもしっかりとTDD開発を実現してくれることがわかりました。

実際のプロジェクトではまた異なってきますので、今後はより実際の開発に近い形で今回のワークフローを検証できればと考えています。

生産性と品質を引き上げるための一つの手段として参考にしていただけると幸いです。

Gaji-Labo フロントエンドエンジニア向けご案内資料

Gaji-Labo は フロントエンドのAI開発の実績と知見があります

急速に進化するAI技術、進まないUIとの統合…。
ユーザー体験を損なわずにAIを導入したいと考えながら、実装や設計に悩み、開発が停滞している。
そんな課題を抱えるプロダクトや開発チームを、私たちは数多く支援してきました。

フロントエンド開発の専門企業である Gaji-Labo は、AIチャットや自然言語処理UIなどの設計・実装において、AIの特性を踏まえた体験設計・UI開発・運用まで、フェーズに応じたサポートが可能です。

フロントエンドでのAI導入を相談する!

タグ


投稿者 Ishigaki Shotaro

未経験から Gaji-Labo に入社。現在は React/TypeScript/Next.js の案件で MUI を使ったコンポーネント組み込みを担当。プロジェクトチームのリードとして共に組み込み作業をしているメンバーの進行管理も行っています。休日はだいたい家で音楽を聴いており、たまにライブに出かけています。