無料活用テクニック

WindsurfのCascadeでTDDサイクルを自動化する実践

·21 min read·Nexeed Lab
WindsurfTDDテスト駆動開発Cascade

WindsurfのCascade AIでTDD(テスト駆動開発)を実践する方法を、.windsurfrules設定からカバレッジ向上まで解説します。

テストを書くのが苦手なエンジニアへ

「動いているのだからテストはあとでいい」 「テストを書く時間がない」 そんな気持ちは、エンジニアなら一度は経験するはずだ。 しかしTDD(テスト駆動開発)は、後からバグを修正する手間を大幅に減らし、コードの設計品質を継続的に高める実証された開発手法だ。 TDDを習慣にするには「テストを先に書く」という思考の切り替えが必要で、その最初の一歩が意外と高いハードルになる。

WindsurfのAIコーディングアシスタント「Cascade」を活用すると、このハードルが大きく下がる。 テストを先に書かせ、実装を生成させ、リファクタリングの提案まで受けられるため、Red-Green-Refactorサイクルを自然と回せる開発スタイルが手に入る。 この記事では、Cascade AIと連携してTDDを日常の開発フローに組み込むための具体的なテクニックを、実践的な設定例・プロンプトとともに紹介する。

Cascade AIとTDDの相性が良い理由

WindsurfのCascadeは、プロジェクト全体のコードベースを読み込んだ上でコード生成・編集・テスト作成を行うAIアシスタントだ。 コンテキストを広く保持した状態で応答するため、テストと実装の関係を理解しながら作業を進められる点がTDDとの親和性を高めている。

CascadeでTDDを実践する際の基本的な発想は次のとおりだ。

  • テスト仕様(何をテストしたいか)を自然言語でCascadeに伝える
  • CascadeにテストコードのみをまずRed状態(失敗する状態)で生成させる
  • その後、テストが通る最小限の実装コードを生成させる
  • 最後にリファクタリングの提案をCascadeに求める

このサイクルをCascadeとの対話の中で繰り返すことで、AI補助によるTDDが自然なリズムで進められる。 通常のコーディング支援ツールとは異なり、Cascadeはプロジェクト全体の文脈を把握しているため、テストと実装が矛盾しないコードを一貫して生成できる。

Red-Green-RefactorサイクルをCascadeで回すプロンプト設計

CascadeにTDDを実践させるには、プロンプトの書き方が大きく影響する。 ポイントは「テストを先に」「実装は後で」という順序を明示することだ。 順序を指定しないと、Cascadeは実装とテストを同時に生成しようとすることがある。

Red フェーズ(失敗するテストを書く)

まず、テストコードだけを生成させるプロンプトを使う。

以下の仕様でVitest用のテストコードのみを書いてください。
実装コードは書かないでください。

仕様:
- ユーザーのメールアドレスを受け取り、形式が正しければtrueを返す
- 空文字・nullの場合はfalseを返す
- @を含まない文字列はfalseを返す
- ドメイン部分が存在しない場合はfalseを返す

関数名: validateEmail
ファイルパス: src/utils/validateEmail.test.ts

「実装コードは書かないでください」という制約を明示することで、CascadeはテストファイルのみをRed状態で作成する。 テストを実行すると「validateEmailが存在しない」というエラーが出るはずで、これがTDDの正しいスタート地点だ。

Green フェーズ(テストを通す最小限の実装を書く)

テストが準備できたら、次のプロンプトで実装を依頼する。

src/utils/validateEmail.test.ts のテストがすべてパスするように、
最小限の実装コードを src/utils/validateEmail.ts に書いてください。
過度な最適化や追加機能は不要です。
テストを通すことだけを目標にしてください。

「最小限の実装」「テストを通すことだけ」という制約を明示することで、Cascadeが過剰実装を避けてGreenフェーズの目的に集中した生成を行うようになる。 余分な機能を実装してしまうと、次のRefactorフェーズで何を改善すればいいかが曖昧になる。 この段階では「動けばよい」という割り切りが重要だ。

Refactor フェーズ(コードを改善する)

テストがGreenになったら、リファクタリングを依頼する。

src/utils/validateEmail.ts の実装コードをリファクタリングしてください。
テストはすべてパスしたままにすること。
改善できる点があれば理由とともに提案してから変更してください。

「テストはすべてパスしたままにすること」という制約がリファクタリングの安全網として機能する。 この三段階のプロンプトパターンを繰り返すことで、CascadeとともにRed-Green-Refactorサイクルを体系的に回せる。 一度パターンに慣れると、Cascadeとのやり取りが自然なTDDのリズムとして身につく。

.windsurfrules でテストファースト方針をプロジェクト全体にルール化する

個々のプロンプトで都度TDDを指示するのは手間がかかる。 .windsurfrules ファイルを使うと、プロジェクト全体にテストファースト方針を設定として埋め込めるため、毎回の指示が不要になる。

.windsurfrules はプロジェクトルートに配置するルールファイルで、Cascadeの振る舞いをプロジェクトレベルでカスタマイズできる。 チームで開発する場合、このファイルをリポジトリにコミットすることで、全員が同じTDDルールのもとでCascadeを使える環境が整う。

以下は、TDD実践のための .windsurfrules 設定例だ。

# テスト方針
- 新しい関数・クラスを実装する前に、必ずテストコードを先に作成すること
- テストフレームワークはプロジェクトのpackage.jsonに記載されているものを使用する
- テストファイルの命名規則: {対象ファイル名}.test.{拡張子}
- テストは Red(失敗) → Green(成功) → Refactor の順で進めること
- カバレッジ目標: 全体80%以上を維持する

# コード生成ルール
- 実装コードを生成する際は、対応するテストコードが存在するか確認する
- テストコードが存在しない場合は、実装前にテストを作成するよう促す
- 1関数1機能の単一責任原則に従う
- テスト可能性(Testability)を優先した設計にする

# テスト品質ルール
- テスト間でグローバル状態を共有しないこと
- 正常系だけでなく、境界値・異常系・エッジケースも必ずカバーすること
- 非同期処理は必ず await/Promise を適切に使用すること
- 意味のないアサーション(expect(x).toBeDefined() のみなど)は避けること

この設定を行うと、Cascadeは新しいコードを生成する際に自動的にテストファースト方針に従った提案を行うようになる。 プロジェクト全体で一貫したTDDの文化を根付かせたい場合、この設定はプロジェクト開始時から行うことを強くすすめる。 後から設定しても効果はあるが、早いほど修正コストは小さい。

既存コードへのテスト追加をCascadeに効率よく依頼する指示パターン

新規開発だけでなく、既存コードへのテスト追加もCascadeが得意とする作業だ。 ポイントは「どのコードのテストを」「どのケースで」「どのフレームワークで」追加したいかを明確に伝えることだ。 あいまいな指示では、Cascadeが当たり障りのない正常系テストだけを生成しがちになる。

関数単位でテストを追加する基本パターン

src/services/userService.ts の getUserById 関数に対して、
以下のケースをカバーするテストを src/services/userService.test.ts に追加してください。

テストケース:
- 存在するユーザーIDを渡した場合、該当ユーザーオブジェクトを返す
- 存在しないユーザーIDを渡した場合、nullを返す
- データベースエラーが発生した場合、例外をスローする

テストフレームワーク: Jest
モック対象: データベース接続部分(db.findById)

「関数名」「テストケースの箇条書き」「フレームワーク」「モック対象」をセットで伝えると、Cascadeは的確なテストコードを生成しやすくなる。 仕様を箇条書きで渡すことで、CascadeがテストケースをそのままDescribeブロック・テスト名として使えるため、読みやすいテストコードが生成される傾向がある。

カバレッジが低い部分を特定してテストを追加するパターン

カバレッジレポートを確認した後、低カバレッジ箇所のテストをCascadeに依頼する際の指示パターンがある。

src/utils/dateFormatter.ts のカバレッジは現在40%です。
このファイルの未テスト部分を特定し、テストケースを提案してから、
テストコードを src/utils/dateFormatter.test.ts に追加してください。
テスト追加後のカバレッジが80%以上になることを目標にしてください。

「カバレッジ目標を数値で示す」ことで、Cascadeは重要なエッジケースを見落とさずにテストケースを設計するようになる。 数値目標があると、生成するテストケースの量と質の両面でCascadeが積極的に取り組む傾向がある。

副作用を持つ関数のモックとテスト

APIコール・ファイル操作・データベースアクセスなど副作用を持つ関数のテストには、適切なモック設定が必要だ。 Cascadeに依頼する際は副作用の種類を明示することで、正しいモック手法を選んだコードが生成される。

src/api/fetchWeather.ts の関数をテストしてください。
内部でfetchを使ったAPIコールがあるため、jest.fn()でモックしてください。
以下のケースをカバーすること:
- 正常なJSONレスポンスが返った場合
- fetchが例外をスローした場合
- HTTPステータスが200以外の場合

テストファイル: src/api/fetchWeather.test.ts

モック対象を「fetch」と明示することで、CascadeはNode.js環境での適切なモック実装を選択できる。 フレームワークやランタイムによってモックの書き方が変わるため、環境情報も一緒に伝えるとより精度が上がる。

AI生成テストの品質をVitest・Jest・pytestで検証・修正する手順

Cascadeが生成したテストコードは、そのまま信頼するのではなく品質を検証する姿勢が大切だ。 AIはコードパターンを学習して生成するため、テストとして機能しているように見えても実際には価値の薄いコードが生まれることがある。

まず実行して確認する

テスト品質確認の第一歩は、実際にテストを実行することだ。 JavaScriptプロジェクトでVitestを使う場合は次のコマンドで実行できる。

# テストを実行してカバレッジを確認する
npx vitest run --coverage

# 特定のファイルのみテストする
npx vitest run src/utils/validateEmail.test.ts

# ウォッチモードで継続実行する(開発中に便利)
npx vitest --watch

Jestなら npx jest --coverage、Pythonのpytestなら pytest --cov=src でカバレッジ付きの実行が確認できる。 テストを実行したとき、予想外にすべてパスする場合は「テスト自体が正しく失敗を検出できているか」を疑うべきだ。

AI生成テストでよくある問題パターン

AI生成テストには典型的な問題パターンがいくつかある。

  • 過剰なモック: 本来テストすべき内部ロジックまでモックしてしまい、テストの意味が薄れている
  • テスト間の依存: グローバル状態が残ることで、テストの実行順序によって結果が変わる
  • エッジケースの漏れ: 正常系のみカバーして、境界値・異常系・null/undefinedケースが抜けている
  • 非同期処理の未待機: awaitが不足して非同期テストが正しく評価されていない
  • 意味のないアサーション: expect(x).toBeDefined() のように何でも通るアサーションで形だけのテストになっている

これらを発見したら、Cascadeに具体的な問題を伝えて修正を依頼する。

src/utils/validateEmail.test.ts を確認したところ、以下の問題があります。
修正してください。

問題点:
1. テスト間でグローバル変数 callCount が共有されており、実行順序に依存しています
2. 境界値テスト(空白のみの文字列、長すぎるメールアドレス)が不足しています
3. 非同期処理の await が欠けている箇所が2か所あります

これらを修正した上で、テストを再実行してすべてパスすることを確認してください。

問題を箇条書きで具体的に指摘することで、Cascadeは的確な修正コードを生成しやすくなる。 「なんかおかしい」という曖昧な伝え方より、「〇〇行目の〇〇が問題」という具体的な指摘が精度を上げる近道だ。

テストカバレッジの可視化とCascadeによるカバレッジ向上ループ

テストカバレッジを定期的に確認してCascadeにフィードバックすることで、継続的にカバレッジを改善できる。 このループを習慣化することが、TDDを長期的に維持するカギになる。

カバレッジレポートをプロンプトに活かす

ViTestやJestのカバレッジレポートには、どのファイルのどの行がテストされていないかが明示される。 この情報をCascadeへのプロンプトに貼り付けることで、的確なテスト追加依頼ができる。

たとえばカバレッジレポートで src/utils/priceCalculator.ts が55%と表示されていた場合、次のようなプロンプトが使える。

カバレッジレポートによると src/utils/priceCalculator.ts のカバレッジは55%です。
以下の未カバー行に対するテストを追加してください:

- 38行目: 割引率が100%を超える場合の処理
- 52〜55行目: 税率が0の場合の計算分岐
- 71行目: 商品点数が0件の場合のエラーハンドリング

各ケースについてテストを src/utils/priceCalculator.test.ts に追記し、
追加後のカバレッジが75%以上になることを確認してください。

行番号を指定することで、Cascadeがコードの対象部分を正確に把握して的確なテストを生成しやすくなる。 カバレッジレポートはHTMLレポートで確認するか、コンソール出力の未カバー行(Uncovered Lines)欄から数値をコピーするだけでよい。

Cascadeとのカバレッジ向上ループを回す

実際の開発では次のサイクルを繰り返すと効果的だ。

  1. npx vitest run --coverage でカバレッジを確認する
  2. カバレッジが低いファイルや未カバー行をCascadeに伝える
  3. Cascadeが追加テストを生成する
  4. テストを実行してパスを確認する
  5. カバレッジが目標値(例:80%)を達成するまで繰り返す

スプリントのレトロスペクティブや週次レビューのタイミングでこのループを回すだけでも、テストカバレッジは着実に向上する。 完璧なカバレッジを一気に目指すのではなく、少しずつ改善するペースが長続きのコツだ。 また、カバレッジの数値だけを追うのではなく、追加したテストが本当に有意義なケースを検証しているかを確認する習慣も大切だ。

windsurfrules にカバレッジ目標を明記する

前述の .windsurfrules にカバレッジ目標を記述しておくと、Cascadeがコード生成のたびにカバレッジを意識した提案を自動的に行うようになる。 プロジェクトの初期段階から設定しておくと、後から修正コストをかけずにTDDの文化を根付かせられる。 カバレッジ目標の数値はプロジェクトの性質に応じて設定するとよい。 ビジネスロジックが複雑なサービスなら80〜90%、プロトタイプ段階なら60〜70%など、現実的な目標から始めることが継続のカギになる。

まとめ:CascadeとTDDで開発品質を継続的に高める

WindsurfのCascade AIを使ったTDD実践のポイントをまとめると次のとおりだ。

  • Red-Green-Refactorの各フェーズを明示したプロンプトを使うことで、AIがTDDの順序を守った生成を行う
  • .windsurfrules にテストファースト方針を記述することで、毎回の指示なしにプロジェクト全体でTDDが徹底できる
  • 既存コードへのテスト追加は「対象関数・テストケースの箇条書き・モック対象」を明確に指示すると精度が高まる
  • AI生成テストは過剰モック・エッジケース漏れ・非同期処理の問題が出やすいため、実行確認と修正依頼をセットで行う
  • カバレッジレポートをCascadeへのフィードバックとして使い、継続的に向上ループを回す

TDDは「書くのが大変」な手法ではなく、「書き始めるまでが大変」な手法だ。 CascadeというAIペアプログラマーが常に隣にいると考えると、テストファーストの一歩を踏み出しやすくなる。 今日から .windsurfrules の設定とプロンプトパターンを試して、少しずつTDDを日常の開発スタイルに取り込んでほしい。

参考資料

この記事をシェア

XFacebookはてブ