プロンプトから作る受け入れテスト:機能をシナリオに落とす
各機能プロンプトを5〜10件の明確なシナリオに落とし込み、ハッピーパスとエッジケースをカバーして過剰なテスト無しで受け入れテストを作る方法を解説します。

なぜプロンプトは見落としを生むのか
チャット調の機能プロンプトは会話のように読みやすいため、一見すると明快に見えます。しかし、選択肢やルール、例外を数行の親しみやすい文に詰め込んでいることが多いです。そのギャップは、誰かが実際に機能を使うまで表面化しません。
多くのプロンプトは前提に頼っています:誰がその操作を行えるのか、「成功」と見なすのは何か(保存、送信、公開、支払い)、データが足りないときはどうなるか、失敗時にユーザーが何を目にするか。さらに「十分に速い」「十分に安全」といったあいまいな基準も隠れています。
あいまいさは通常、バグや手戻りとして遅れて現れます。開発者はプロンプトが意味するところを作り、レビュワーは見た目で承認し、そしてユーザーが重複投稿、タイムゾーン、部分的なデータ、権限の不一致といった変なケースに当たります。後から直すコストが高いのは、しばしばコード、UI文言、場合によってはデータモデルにも手を入れる必要があるからです。
品質に大量のテストは必要ありません。通常利用と予測可能な負荷に耐えうる信頼があることです。よく選ばれた少数のシナリオがあれば、何百ものテストなしにその信頼を得られます。
プロンプトから作る機能に対する実用的な品質定義:
- メインのユーザーゴールがエンドツーエンドで動く(ハッピーパス)。
- 主要な失敗モードがきちんと扱われる(明確なエラー、無音の破損がない)。
- 機能が一貫して振る舞う(同じ入力なら同じ結果)。
- 偶発的に危険なことが起きない(誤ユーザーのアクセス、重複操作)。
これがプロンプトを受け入れシナリオに変える目的です:あいまいな要求を取り出し、隠れたルールを早期に洗い出すための5〜10件のチェックに落とし込む。全てをテストするのではなく、実際に起きる失敗を先に捕まえることを目指します。
たとえばKoder.aiのような即席のvibe-codingツールから始めると、出力は一見完結して見えてもエッジルールを飛ばしていることがあります。緊密なシナリオセットは、変更がまだ安価なうちにそれらのルールに名前を付けさせます。
良い受け入れテストシナリオとは
受け入れテストシナリオは、ユーザーの操作と表示される結果を短く平易に記述したものです。
表面に留まってください:ユーザーが何をできるか、製品が何を表示・変更するか。データベースのテーブル、API呼び出し、バックグラウンドジョブ、使っているフレームワークなどの内部詳細は避けます。これらは後で重要になるかもしれませんが、シナリオを脆くし、合意しにくくします。
良いシナリオはまた独立しているべきです。翌日クリーンな環境で簡単に実行でき、別のシナリオの実行を前提としないこと。前提状態が必要ならセットアップで明確に書きます(例:「ユーザーは既にアクティブなサブスクリプションを持っている」)。
使えるシンプルな形
多くのチームはGiven-When-Thenを使います。これによってシナリオが明確になりつつもスペックになりすぎません。
シナリオは通常、1つのゴール、明確な開始状態、具体的な操作、そして可視の結果を持つと“完了”です。二値的であり、チームの誰でも実行後に「合格/不合格」と言えるべきです。
例:「Given サインイン済みで支払い方法が保存されていないユーザー、When Proを選び支払いを確定、Then 成功メッセージが表示され、アカウントにProが表示される。」
チャットファーストのビルダー(例:Koder.ai)で構築する場合も同じルールを守ってください:生成されたアプリの挙動(ユーザーが体験すること)をテストし、プラットフォームがどうコードを作ったかはテストしないこと。
チームが実際に使う形式を選ぶ
ベストな形式は、実際に人が書き読みするものです。チームの半分が長い物語形式で、残りが短い箇条書きだと、ギャップや重複、表現の議論が品質の代わりに増えます。
機能がインタラクティブで状態を持つならGiven-When-Thenが有効です。入力–出力ルールが多く似たケースが並ぶならシンプルな表がスキャンしやすいです。
チームが分かれているなら、30日間ひとつの形式を採用してから調整しましょう。レビュワーが「成功がどう見えるか?」と聞き続けるならGiven-When-Thenに寄せるサインです。シナリオが冗長になっているなら表の方が読みやすいでしょう。
何を選んでも標準化してください。同じ見出し、同じ時制、同じ詳細レベルを保ち、含めないことにも合意します:ピクセル単位のUI、内部実装、データベースの話。シナリオはユーザーが見るものと、システムが保証することを記述すべきです。
シナリオをどこに保管するか
シナリオは作業がすでに起きている場所に置き、機能に近づけてください。
一般的な選択肢としては、プロダクトコードの隣、チケット内の「Acceptance scenarios」セクション、あるいは機能ごとの共有ドキュメントページなどがあります。Koder.aiを使っているなら、Planning Modeにシナリオを置いておくことでスナップショットやロールバックポイントと一緒にビルド履歴に残せます。
重要なのは検索可能にし、一つの真実のソースを持ち、開発開始前にシナリオを要求することです。
ステップバイステップ:1つの機能プロンプトを5〜10件のシナリオに変える方法
まずプロンプトを書き直して、ユーザーゴールと明確な終了線を出します。ゴールは1文で(誰が何をしたいか)、次に2〜4件の成功基準を挙げます。目に見える成果が指せないなら、それはまだテストではありません。
次にプロンプトを入力、出力、ルールに分解します。入力はユーザーが提供するもの、出力はシステムが表示、保存、送信、またはブロックするもの、ルールは行間にある「〜のときだけ」「必須」などです。
次に、その機能が動くために何が前提かを確認します。ここにシナリオのギャップが隠れていることが多い:必要なデータ、ユーザーロール、権限、連携、システム状態など。例えばKoder.aiでアプリを作るなら、ユーザーがログインしている必要があるか、プロジェクトが作成済みであるか、どのプランやアクセス要件が必要かを明確にしてください。
そして機能が動くことを証明するための最小限のシナリオ群を書きます:通常は1〜2のハッピーパスと4〜8のエッジケース。各シナリオは1つの失敗理由に集中させます。
選ぶべき良いエッジケース(プロンプトに合うものだけ):入力の欠損や不正、権限ミスマッチ、「既に提出済み」のような状態の競合、タイムアウトなど外部依存の問題、回復動作(明確なエラー、安全な再試行、部分保存なし)です。
最後に「何がまずいか?」の簡単なチェックをします。静かな失敗、わかりにくいメッセージ、システムが誤ったデータを作る箇所を探します。
ハッピーパスの書き方(深く考えすぎないコツ)
ハッピーパスは最も短く普通の経路です。意図的に退屈に書くと、それが信頼できる基準になり、後でエッジケースを見つけやすくなります。
デフォルトのユーザーとデフォルトのデータを明記してください。「User」ではなく「認証済みでメール確認済みの顧客」や「請求編集権限を持つ管理者」などの実役割にします。次に最小のサンプルデータを定義します:1プロジェクト、リストの1アイテム、1つの保存済み支払い方法。こうすることでシナリオが具体的になり、隠れた前提を減らせます。
成功までの最短経路をまず書き、オプション手順や代替フローは除きます。例えば「タスクを作成する」機能なら、ハッピーパスにフィルタやソート、作成後の編集は含めないでください。
簡単に絞るには次の4点を確認します:
- ユーザーが適切な画面/状態を適切なタイミングで見ること。
- システムが適切なメッセージ(成功、確認、次の指示)を表示すること。
- データが保存されること(どう保存されるかではなく何が保存されるか)。
- ユーザーが次に進めること(次に合理的なアクションが可能)。
その後、変数を一つだけ変えたバリアントを1つ追加します。壊れやすい変数(例:長いタイトル、ユーザーに既存アイテムがない)を選んで残りは同じにします。
例:プロンプトが「スナップショット保存後に「Snapshot created」トーストを表示する」と言うなら、ハッピーパスは:ユーザーがCreate Snapshotをクリック、ローディング状態、"Snapshot created"が表示され、スナップショットが正しいタイムスタンプでリストに現れる、です。バリアントは名前が空欄の場合にデフォルト命名ルールが適用される、などです。
小さなエッジケースメニュー(選ぶべき項目)
エッジケースはバグの温床ですが、検出するために巨大なスイートは不要です。各プロンプトに対して、実際の挙動と現実的な失敗モードを反映する小さな集合を選びます。
よくあるカテゴリ:
- 入力問題(空、長すぎる、形式不正、特殊文字)
- 状態問題(権限なし、セッション切れ、必要なデータがない、アカウント未検証)
- 同時実行問題(ダブルクリックで2回送信、複数タブで同時編集、スピナー中のリトライ)
- 統合問題(タイムアウト、プロバイダ不在、部分失敗、レート制限)
- データ問題(重複、途中で削除されたレコード、古いデータ、丸め誤差)
全ての機能が全カテゴリを必要とするわけではありません。検索ボックスは入力関係が重要ですし、支払いフローは統合とデータが重要です。
リスクにマッチするエッジケースを選びます:失敗のコストが高い(お金、セキュリティ、プライバシー)、頻度が高い、壊れやすいフロー、過去に起きたバグ、後から検出しにくい問題などです。
例:サブスクリプションプラン変更では、チェックアウト中のセッション切れ、Confirmのダブルクリック、支払いプロバイダのタイムアウトでプランが変わらないケースに対処するシナリオが有効です。
実例:一つの機能プロンプトをタイトなシナリオセットにする
例の機能プロンプト(プレーン言語):
"何か壊したときに、前のスナップショットにロールバックして、最後に動いていたバージョンを再度公開したい。"
以下はコンパクトなシナリオセットです。各シナリオは短いですが結果を特定します。
ハッピーパス(2件)
S1 [Must-have] 最新のスナップショットへロールバック
Given 私はログインしており、そのアプリの所有者である
When 「Rollback」を選び確認する
Then アプリは前のスナップショットをデプロイし、アプリのステータスがそのバージョンをアクティブとして表示する
S2 [Must-have] 特定のスナップショットへロールバック
Given 私はアプリのスナップショット一覧を見ている
When スナップショット「A」を選択しロールバックを確認する
Then スナップショット「A」がアクティブバージョンになり、作成日時が確認できる
エッジケース(6件)
S3 [Must-have] 権限なし(認可)
Given 私はログインしているがこのアプリへのアクセス権がない
When ロールバックを試みる
Then アクセスエラーが表示されロールバックは開始されない
S4 [Must-have] スナップショットが見つからない(検証)
Given スナップショットIDが存在しない(または削除されている)
When そのスナップショットへロールバックを試みる
Then 「スナップショットが見つかりません」という明確なメッセージが表示される
S5 [Must-have] 二重送信(重複)
Given 私が「Confirm rollback」を素早く2回クリックした
When 2回目のリクエストが送信される
Then ロールバックは1回だけ実行され、結果は1つだけ表示される
S6 [Must-have] デプロイ失敗(障害)
Given ロールバックが開始された
When デプロイが失敗する
Then 現在のアクティブバージョンがそのまま稼働し、エラーが表示される
S7 [Nice-to-have] タイムアウトや接続喪失
Given ロールバックの途中で接続が切れる
When ページをリロードする
Then ロールバックがまだ実行中か完了したかを確認できる
S8 [Nice-to-have] 既にそのスナップショットがアクティブ
Given スナップショット「A」が既にアクティブである
When スナップショット「A」へロールバックを試みる
Then 何も変わらなかったと伝えられ、新たなデプロイは開始されない
各シナリオは「誰が、何をし、後に何が真であるべきか」の3点に答えます。
カバレッジを高く、スイートを小さく保つ方法
目標は「全てをテストする」ことではなく、ユーザーに害を及ぼすリスクをカバーすることです。それでいて誰も実行しない膨大なシナリオ山を作らないこと。
実用的なトリックとして、シナリオに利用用途タグを付けるとよいです:
- Smoke: 機能がエンドツーエンドで動くことを証明する1〜2件。
- Regression: 重要なルールや過去のバグに対する2〜6件。
- Exploratory: 奇妙なケースやUX判断のための数件の「試してみる」チェック。
異なるリスクごとに1シナリオに絞ってください。原因が同じで2件失敗するなら1件で十分な場合が多いです。「無効なメール形式」と「メールが欠損」は異リスクですが、「ステップ1でのメール欠損」と「ステップ2でのメール欠損」は同一ルールならまとめられます。
また多くのシナリオでUI手順を繰り返し書くのは避けて、繰り返し部分は短くして差分に注目します。チャットベースのツール(Koder.aiなど)で作るとUIが変わりやすいため、この点はさらに重要です。
最後に、今チェックすることと後回しにすることを決めます:
- 今は手動で:文言、レイアウト、視覚状態、「分かりにくい」箇所。
- すぐ自動化:計算、権限、データの正しい保存、重要なフロー。
- あとで自動化:稀な端末特有の問題、珍しいブラウザのタイミング、サードパーティ障害。
シナリオを無意味にするよくある間違い
シナリオは驚きを防ぐためのもので、チームの実装計画を書くためのものではありません。
最も一般的な失敗はユーザーゴールを技術チェックリストに変えてしまうことです。シナリオに「APIが200を返す」や「テーブルXにカラムYがある」と書くと、設計に縛られつつもユーザーが本当に得たものを証明しません。
もう一つの問題は複数のゴールを一つの長いシナリオに詰め込むことです。長い旅路のように読めても、失敗したときに誰も原因を特定できません。1シナリオは1つの疑問に答えるべきです。
また本当に現実的でないエッジケース(ユーザーが1,000万プロジェクト持っている、2秒ごとにネットワークが切れる等)は再現が難しく役に立ちません。数分で用意できるエッジケースを選んでください。
「動く」「エラーなし」「正常に完了」などの曖昧な結果も避けます。これらは検証すべき具体的な結果を隠してしまいます。
「役に立つ」 vs 「役に立たない」の短い例
Koder.aiの「ソースコードをエクスポート」機能のようなものを作る場合、弱いシナリオは:「ユーザーがエクスポートをクリックすると、システムはリポジトリをzipして200を返す」です。実装をテストしているだけで約束を検証していません。
より良いシナリオは:「スナップショットが2つあるプロジェクトで、ユーザーがエクスポートすると、ダウンロードには現在のスナップショットのコードが含まれ、エクスポートログに誰がいつエクスポートしたかが記録されている」などです。
「権限のないユーザーがエクスポートしようとしたら、そのオプションが隠されるかブロックされ、エクスポート記録が作られない」といった“No”パスも忘れないでください。一行でセキュリティとデータ整合性の両方を守れます。
受け入れシナリオセットを受理する前のクイックチェックリスト
シナリオセットを“完了”と見なす前に、面倒なユーザーとデータベースの両面でチェックしてください。開始時に何が必要か、成功が何かが分からないなら準備不足です。
良いセットは小さく具体的です。書いた人と同じでない人に渡しても同じ結果が得られるべきです。
承認(または差戻し)のための簡単な確認項目:
- 各シナリオにひとつの明確な前提とひとつの主要な結果がある。
- 期待結果はユーザーが見るものと保存されるものを含む。
- 権限が重要な場合は許可されるケースと拒否されるケースの少なくとも1件ずつがある。
- 重要な連携は現実的な失敗モードを少なくとも1件含む。
- セットは5〜10件の範囲に収まり、重複がない。
チャットベースのビルダーでシナリオを生成している場合も同じ基準を適用してください:「期待どおりに動く」だけの曖昧さは不可です。観察可能な出力と保存された変更を要求し、検証できるものだけを承認します。
次の一手:プロンプト→テストをワークフローに組み込む
シナリオ作成を作業の終わりの掃除タスクにせず、実際の工程ステップにしてください。
実装前にシナリオを書くことで、修正コストが低いうちに対処すべき厄介な質問に答えさせます:成功とは何か、不正入力でどうなるか、現時点で何をサポートしないか。
シナリオを“完了の定義”として使いましょう。プロダクトは意図を持ち、QAはリスク思考を、エンジニアリングは実現可能性を担当します。3者が同じシナリオセットを読んで合意できれば、「完成したけど受け入れられない」ものを出荷するリスクを避けられます。
多くのチームで有効なワークフロー:
- 各機能プロンプトを1ハッピーパスと少数のエッジケースを含む5〜10件のシナリオに変える。
- それを素早くレビューして、未解決の質問を平易な言葉で解決する。
- シナリオに書かれた通りに実装し、実装中に新しい要件が出たらシナリオを追加する。
- レビューでは「見た目が良い」ではなく、シナリオを受け入れチェックリストとして使う。
- プロンプトが変わったらシナリオも更新し、テストが現実に合うようにする。
Koder.ai(koder.ai)で作る場合は、まずシナリオをPlanning Modeで下書きしてから画面やデータルール、ユーザーに見える結果をマッピングすると、コード生成や編集前に要件を固めやすくなります。
リスクの高い変更には、作業前にスナップショットを取りましょう。新しいエッジケースが動作中のフローを壊したとき、ロールバックすれば副作用を解くのに一日を費やさずに済みます。
シナリオは機能要求のそば(または同じチケット内)に置き、バージョン管理された要件として扱ってください。プロンプトが進化したらシナリオセットも進化させないと、“完了”の意味が静かにずれていきます。
よくある質問
How do I turn a feature prompt into acceptance scenarios without writing a full spec?
まず1文でユーザーのゴールと終了条件を書きます。
その後、プロンプトを次に分解します:
- 入力(ユーザーが与えるもの)
- 出力(システムが表示/保存/送信/ブロックするもの)
- ルール(「〜のときだけ」「必須」「例外」など)
そこから、1〜2件のハッピーパスと、実際のリスクに合った4〜8件のエッジケースを書きます(権限、重複、タイムアウト、データ欠損など)。
Why do chat-style prompts so often miss requirements?
プロンプトは前提を隠していることが多いからです。プロンプトは「保存する」と言っても、それが下書きか公開か、失敗時にどうするか、誰が許可されているかを定義していないことがあります。
シナリオはそれらのルールを早期に名前で定義させるので、重複投稿や権限ミスマッチ、一貫しない結果といったバグを事前に防げます。
What scenario format should my team use: Given–When–Then or a table?
機能が状態を持ち、ユーザー操作が絡むときはGiven–When–Thenが有効です。
類似ルールが多く並ぶ場合は、シンプルな入力/出力の表が見やすいです。
チームが分かれているなら、まず30日間ひとつの形式に決めて運用し、必要なら調整しましょう。レビューで「成功がどう見えるか?」とよく問われるならGiven–When–Thenに寄せるべきです。文字数が増えすぎるなら表の方が読みやすいかもしれません。
何を選ぶにしても標準化してください。見出し、時制、詳細レベルを揃え、ピクセル単位のUIや実装詳細(DBやフレームワーク)は含めないことに合意しておきます。
What makes an acceptance test scenario “good”?
良いシナリオは:
- 二値的(明確な合格/不合格)
- ユーザーに見える(ユーザーの操作と見える結果)
- 独立している(クリーンな環境で実行できる)
- 具体的(「動く」「エラーなし」ではなく検証できる結果)
誰でも実行して結果に合意できれば、そのシナリオは“完了”と見なせます。
What should I avoid putting in acceptance scenarios?
観察可能な挙動に集中してください:
- ユーザーがクリック/入力すること
- システムが表示するもの(メッセージ、状態)
- 永続化される変更(作成/更新/ブロック)
避けるべきは実装の詳細:DBテーブル、APIレスポンスコード、バックグラウンドジョブ、使用しているフレームワークなど。これらは頻繁に変わり、ユーザーが得た結果を証明しません。
How do I write a happy path scenario without overthinking it?
「最も退屈で普通の経路」を書いてください:
- 実際の役割を明記する(例:「認証済みでメール確認済みの顧客」)
- 最小限の現実的なデータを使う(一つのプロジェクト、一つのアイテム)
- 手順は短く(オプションや別フローを含めない)
その後、4点を確認します:正しい画面/状態、明確な成功メッセージ、データが保存されること、次に進めること。
さらに変数を一つだけ変えたバリアントを作れば充分です(例:タイトルが長い、既存アイテムがないなど)。
Which edge cases are worth testing first?
リスクと頻度で選びます:
- 入力問題(空、長すぎる、形式不正、特殊文字)
- 権限・セッション問題(アクセスなし、ログイン切れ)
- 状態の競合(既に提出済み、既に有効)
- 同時実行(ダブルクリック、複数タブ)
- 統合の失敗(タイムアウト、プロバイダ不在)
目的は異なるリスクごとに1シナリオを作ることです。同じ原因で複数が失敗するなら1つで十分なことが多いです。
What should the app do when something fails (timeouts, errors, partial data)?
安全かつ明確に:
- 部分的に静かに保存しないこと
- 明確なエラーメッセージ(何が起きたか、次に何をすべきか)
- 安全なリトライ(重複アクションを生まない)
- 状態の整合性を保つ(例えばデプロイ失敗時は旧版がそのまま稼働)
失敗シナリオは、データを壊さずユーザーを誤解させないことを証明するべきです。
How does this workflow fit when building in Koder.ai?
Koder.aiのアウトプットも他のアプリと同じ扱いで、プラットフォームがどうコードを生成したかではなく、ユーザーが何を体験するかをテストしてください。
実用的な流れ:
- まずPlanning Modeでシナリオを書く
- 機能を作る
- そのシナリオを受け入れチェックリストとして実行する
- リスクが高い変更はスナップショットを取ってから作業し、問題が出たらすぐ戻せるようにする
Where should we store scenarios so they don’t disappear?
作業が起きている場所に置き、1つの真実のソースを保ってください:
- チケット内の「Acceptance scenarios」セクション
- プロダクトコードの隣
- 機能ごとの共有ドキュメントページ
Koder.aiを使う場合はPlanning Modeにシナリオを置くと、ビルド履歴と紐づけたまま保管できます。最も重要なのは、開発開始前にシナリオを必須にすることです。