テスト

BDDとは?振る舞い駆動開発の仕組みとTDDとの違い・導入判断を実装者向けに解説

BDD(Behavior-Driven Development、振る舞い駆動開発)は、システムが外から見てどう振る舞うかをGiven・When・Thenの三語で書き表し、その記述をそのまま自動テストとして実行する開発の進め方です。テスト手法の一種として紹介されることが多いのですが、出発点にあったのは「同じ仕様書を読んでも、企画・開発・テストで解釈がずれる」という設計側の問題でした。この記事では、BDDの定義とGherkin記法の構文、テスト駆動開発(TDD)との役割分担、Cucumberをはじめとする実行環境の現況(2026年8月時点)、そして導入して割に合う現場と見送るべき現場の線引きまでを、実装する側の視点で整理します。

まとめ:BDDが解くのは仕様の認識ずれで、テスト自動化そのものではない

BDDの本体は、Given(前提)・When(操作)・Then(期待結果)という形式で振る舞いを言語化し、企画・開発・テストの三者が同じ文面を見て仕様を確定する合意プロセスにあります。Cucumberなどのツールはその文面を実行可能にする手段であって、ツールを入れただけでは効果は出ません。

TDDとの関係は競合ではなく階層差です。TDDはコード単位の設計を駆動し、BDDはその上位で「何を作るか」を確定させます。両方を並行して回す現場が実際には多数派です。

導入の分岐点は明快で、仕様の問い合わせが発注者と開発者の間で週単位に往復している現場なら投資は回収できます。逆に、仕様を決める人と書く人が同一で、プロダクトの寿命が数か月なら、シナリオの保守コストが先に効いてくる構図です。判断基準は本記事の後半で条件付きに示します。

振る舞い駆動開発の定義とGiven-When-Thenが生まれた背景

BDDは2000年代半ばにDan North氏が提唱した手法で、TDDを現場に教える過程で見つかった実務上の詰まりが起点になっています。まずは何を解こうとした手法なのかを押さえます。

Dan Northが提唱したBDDの出発点とTDDに残った課題

North氏がTDDを教えていて繰り返し直面したのは、「どのテストを先に書けばよいか分からない」「テスト名がtestAddUserのようになり、何を保証しているのか後から読めない」という質問でした。テストの書き方ではなく、テストが表現している仕様の読みにくさが障害になっていたわけです。

そこで持ち込まれたのが、テストメソッド名を「should〜」で始める規約と、シナリオを「ある前提のもとで、ある操作をしたとき、こうなる」という定型文に固定する発想でした。この定型文がGiven・When・Thenです。テストコードの体裁を変えたのではなく、テストが答えるべき問いの形を固定した点に本質があります。

Given-When-Thenで記述する振る舞いの単位と粒度の目安

1シナリオは1つの振る舞いに対応させます。Givenに書くのはシステムの状態であって、ログイン画面を開くといった操作ではありません。Whenは利用者が起こす出来事を1つだけ、Thenは観測できる結果を書きます。

粒度の目安として、Whenが2つ以上並ぶシナリオは分割の候補です。「ログインして、商品をカートに入れて、決済する」を1本にまとめると、決済の失敗理由がログインなのか在庫なのか切り分けられなくなります。逆に、Thenが1つも書けないシナリオは、そもそも観測可能な振る舞いになっていません。

三者協働でシナリオを確定するBDDの進め方と成果物の位置づけ

BDDの現場運用では、プロダクトオーナー・開発者・テスト担当の三者が同席してシナリオを書く進め方が定着しています。英語圏ではThree Amigosと呼ばれる形式で、実施時間は1ストーリーあたり15分から30分程度に収めるのが通例です。

この場の成果物はシナリオ本体ですが、本当の産出物は「その場で出た質問」のほうです。「未ログインでカートに入れた商品は、ログイン後に引き継ぐのか」といった問いは、実装が半分進んでから出ると大きな手戻りを招く原因です。書かれたシナリオは要件定義書の代わりではなく、合意の記録として振る舞いを固定する役割を担います。アジャイル開発のスクラムの進め方と組み合わせる場合、この会を各スプリントの計画直後に置くと機能します。

テスト駆動開発(TDD)との違いを目的・記述言語・読み手で整理

BDDの説明で最も混乱が起きるのがTDDとの関係です。両者は排他ではなく、扱う抽象度と読み手が違います。

TDDが担うコード品質とBDDが担う仕様合意の役割分担の線引き

TDDはRed・Green・Refactorのサイクルで、クラスやメソッドの設計を内側から駆動します。読み手は書いた本人と同じチームの開発者です。基本サイクルの具体はテスト駆動開発(TDD)の基礎と基本サイクルで扱っています。

一方のBDDは、システム境界の外側から見た振る舞いを対象にします。読み手には非エンジニアが含まれるため、記述言語は自然言語に寄ります。実務では、外側のシナリオをBDDで固定し、その内側の実装をTDDで組み上げる二重ループとして回すのが素直な形です。どちらか一方を選ぶ設問設定自体が、現場の実態とずれています。

同じテストコードでもBDDとTDDで変わる失敗時の読み方の違い

差が最も現れるのは、テストが落ちた瞬間です。TDDのユニットテストが赤くなったら、原因はほぼ直前に触ったコードにあります。修正対象は明確で、調査は数分で終わります。

BDDのシナリオが落ちた場合、意味は二通りに分かれます。実装の不具合か、仕様そのものが変わったか。後者なら直すべきはコードではなくシナリオで、その変更は三者で再合意する対象になります。この分岐があるため、BDDのシナリオはユニットテストと同じ感覚で機械的に直してはいけません。落ちたシナリオを「とりあえず通す」修正を続けると、シナリオは仕様の記録として死にます。

ATDDや仕様例による開発とBDDが重なる範囲と呼称の使い分け

ATDD(受け入れテスト駆動開発)とSpecification by Example(実例による仕様化)は、BDDと大きく重なります。三者で受け入れ条件を先に決め、それを実行可能な形にするという骨格は共通です。

使い分けの実務的な線は、強調点の違いです。ATDDは受け入れテストという成果物を、Specification by Exampleは具体例による曖昧さの排除を、BDDは会話と共通言語を前面に置きます。社内で用語を統一する際は、どれか一語に寄せて定義を1行で共有するほうが混乱は少なくなります。三者三様の呼称を併用する必然性はありません。

Gherkinで書くシナリオの構文とアンチパターンの見分け方

BDDのシナリオは、Gherkinと呼ばれる構造化された自然言語で書かれます。構文自体は十数個のキーワードしかありませんが、書き方を誤ると保守不能な資産に変わります。

FeatureからScenario Outlineまで押さえる構文要素の役割

Gherkinの主要キーワードはFeatureRuleScenarioGivenWhenThenAndButBackgroundScenario OutlineExamplesです。日本語キーワード(前提・もし・ならば など)も主要実装が対応しており、日本語で書いても実行できます。

実務で効くのはBackgroundScenario Outlineの二つです。前者はファイル内の全シナリオに共通する前提をまとめ、後者は入力値だけが違うシナリオを表形式に畳む仕組みです。ただしBackgroundに5行以上の前提を積むと、個々のシナリオが単体で読めなくなります。記法そのものの詳細はGherkinの基本概念と記述言語としての役割にまとめてあります。

UI操作をそのまま書く手順書化がシナリオを壊す典型的な失敗例

最も多い失敗が、シナリオを操作手順書として書いてしまうことです。「ログインボタンをクリックする」「メールアドレス欄に入力する」といった記述が並ぶと、画面のボタン名が変わるだけで数十本のシナリオが同時に落ちます。

書くべきは操作ではなく意図です。「利用者がログイン済みである」と書けば、実装がフォーム認証でもシングルサインオンでも文面は生き残ります。判定の手がかりは単純で、シナリオ本文にHTMLの要素名やボタンのラベルが出てきたら書き直しの対象と考えてください。この境界を守れているかどうかが、1年後にシナリオが残っているかを決めます。

シナリオの陳腐化を防ぐステップ定義の共通化と棚卸しの運用基準

Gherkinの1行は、ステップ定義と呼ばれる実装コードに正規表現などで結び付きます。同じ意味の行を「利用者がログインしている」「ユーザがログイン済み」と揺らして書くと、ステップ定義が二重化して保守量が倍になります。

対策は語彙の固定です。主語と述語の言い回しをプロジェクトの用語集に登録し、新しい言い回しを足すときはレビュー対象にします。加えて、四半期に一度は実行結果を集計し、半年以上一度も落ちていないシナリオを棚卸しの候補に挙げてください。落ちないシナリオは、守っている振る舞いが既に安定しているか、あるいは何も検証していないかのどちらかです。

主要BDDフレームワークの現況と言語別に見た実行環境の選び方

Gherkinを実行する側のツールは言語ごとに分かれています。選定で見るべきは機能差より、開発が継続しているかと既存のテスト資産に乗るかどうかです。

Cucumber系とReqnrollなど言語別フレームワークの版と状況

2026年8月時点で確認できる主要実装の版は次のとおりです。いずれも各リポジトリのリリース情報とパッケージレジストリで実測した値で、更新の活発さの目安として扱ってください。

ツール 主な対象言語 版(2026年8月時点) 位置づけ
Cucumber-JVM Java・Kotlin 7.34系 Gherkin実行の本流
Cucumber-JS JavaScript・TypeScript 13.2系 Node環境の標準的な選択
Cucumber-Ruby Ruby 11.1系 発祥に最も近い実装
Reqnroll .NET 3.3系 SpecFlowのOSS後継
pytest-bdd Python 8.1系 pytest資産へ載せる型
behave Python 1.3系 単体で完結する実装

Python環境では二択になりますが、既にpytestのフィクスチャやプラグインを持っているならpytest-bddを選ぶほうが移行コストは小さくなります。Java環境でのCucumber導入手順はCucumberによるJavaのテスト自動化とGherkin記法で具体例を示しています。

SpecFlowからReqnrollへの移行で確認すべき互換性の範囲

.NET環境で長く使われてきたSpecFlowについては、後継としてReqnrollが公開されています。Reqnrollの公式ドキュメントには、SpecFlowのオープンソース版コードベースを基に作られたこと、SpecFlow v4は正式リリースされずGitHubプロジェクトが削除されたことが明記されています。

移行時の確認点は三つに絞られます。名前空間の置換、プラグインの対応状況、そしてCI上のテストランナー設定です。Gherkinのフィーチャーファイル自体は書式が共通のため、原則としてそのまま持ち込めます。手が止まりやすいのは独自プラグインを作り込んでいるケースで、ここだけは移行前に棚卸ししてください。

CI環境でシナリオを回す際の実行時間と並列化に関する判断基準

シナリオ数が100本を超えたあたりから、実行時間がプルリクエストのフィードバック速度を圧迫し始めます。目安として、開発者が変更のたびに待てるのは10分程度です。

対処の順序は決まっています。まず遅いシナリオの層を下げる、次に不要なシナリオを削る、それでも足りなければ並列化する。並列実行を先に入れると、テストデータの競合という新しい不安定要因を抱え込みます。並列化する場合は、シナリオごとにテストデータを独立させる設計が前提になります。

テストピラミッドの中でBDDシナリオを置く層と適正な本数の上限

BDDが失敗する原因の大半は、記法ではなく配置にあります。シナリオをどの層で実行するかで、保守コストは一桁変わります。

E2E層に寄せすぎたシナリオが招く実行時間の膨張と結果の不安定化

Gherkinで書いた振る舞いを、すべてブラウザ操作として実行すると何が起きるか。1シナリオあたり10秒から30秒かかり、200本で1時間を超えます。加えて、ネットワークや描画待ちに起因する不安定な失敗が混ざり、赤いテストが放置される状態に至ります。

この構造はテストピラミッドによるテスト配分の設計で扱う配分の問題そのものです。E2E層に置くシナリオは、決済完了や登録完了のように「そこが落ちたらリリースを止める」経路だけに絞ってください。目安の本数は、プロダクト全体で10本から30本程度です。

APIやサービス層で振る舞いを検証しシナリオ本数を抑える設計方針

大半のシナリオは、画面を経由せずサービス層やAPI経由で実行できます。「在庫が0の商品は購入できない」という振る舞いは、ブラウザを起動しなくても検証が可能です。実行時間は1シナリオあたり数十ミリ秒から数百ミリ秒に収まります。

設計上のコツは、ステップ定義の実装を差し替え可能にしておくことです。同じGherkin文面に対して、通常はサービス層を叩く実装を割り当て、リリース前の検証時だけ画面経由の実装に切り替える構成なら、文面を二重管理せずに済みます。E2E層の設計判断はE2Eテストのベストプラクティスとツール選定も併せて参照してください。

BDDを導入して割に合う条件と見送るべき現場の具体的な見極め方

ここからは判断を言い切ります。BDDは万能の手法ではなく、投資が回収できる条件がはっきりしている手法です。

発注者と仕様の問い合わせが往復する現場でBDDが効く採用条件

採用して割に合うのは、次の状態にある現場です。仕様に関する問い合わせが週に数件以上発生している。実装後に「想定と違う」という差し戻しが月に1件以上ある。仕様を決める人と実装する人が別の組織に属している。この三つのうち二つ以上が当てはまるなら、シナリオを書く時間は手戻りの削減で回収できます。

逆に言えば、回収されるのはコミュニケーションのコストであって、テスト工数ではありません。BDDを「テスト自動化の効率化施策」として稟議に載せると、期待値がずれて評価も外れます。導入目的は仕様の確定速度に置いてください。

BDDを見送るべき小規模チームと短命プロダクトという二つの条件

見送るべき現場も明確です。第一に、開発者が3名以下で、仕様を決める人が同じチームに常駐している場合。会話で即座に解決できる問いを、わざわざ文書化する手間のほうが上回ります。第二に、想定寿命が半年未満の検証用プロダクトや、社内向けの一時的なツール。シナリオの保守が発生する前に役目を終えます。

この二条件に当てはまる現場では、Gherkinを捨ててTDDと通常のユニットテストに寄せてください。振る舞いの記録が必要なら、テスト名を「should〜」形式で揃えるだけでも大部分は代替できます。BDDの形式を守ること自体には価値がありません。

受託開発でBDDを受け入れ条件として使う場合の契約面での注意点

受託開発では、Gherkinのシナリオを受け入れ条件として契約書に紐づける運用が可能です。検収の判定が「動くこと」から「合意したシナリオが全て通ること」に変わるため、検収時の水掛け論は減ります。

ただし注意点があります。シナリオを契約の一部にすると、追加や変更は仕様変更の交渉対象です。変更手続きを軽くしておかないと、シナリオを増やすこと自体が避けられ、記述が形骸化します。実務では、シナリオの追加は変更管理の対象外とし、既存シナリオの削除だけを合意対象にする運用が扱いやすい形です。社内にこの運用を根付かせる過程では、テスト設計と実行基盤の整備を並行する必要があります。体制づくりから外部の手を借りる場合は、保守運用・内製化支援のように継続的な開発体制まで含めて相談できる相手を選ぶと、シナリオが放置される事態を避けやすくなります。

よくある質問

BDDの導入検討でよく寄せられる質問と、実務上の回答をまとめます。

BDDとTDDはどちらを先に導入すべきですか?

TDDが先です。BDDのシナリオは内側にユニットテストの層があって初めて機能するものです。ユニットテストがない状態でGherkinのシナリオだけを増やすと、落ちた原因を特定できず、実行に時間のかかる不安定なテスト群だけが残ります。まずTDDでユニットテストの土台を作り、仕様の認識ずれが実際に問題として観測できてからBDDを重ねる順序を推奨します。

Gherkinのシナリオは誰が書くのが現実的ですか?

三者で口頭合意し、たたき台の文面は開発者かテスト担当が書くのが現実的です。プロダクトオーナーに単独で書かせると、操作手順の羅列になりやすく、後の保守が破綻する原因です。逆に開発者だけで書くと実装の都合が文面に混ざります。書くのは1名、レビューは3名という分担にすると、時間も品質も収まります。

BDDのシナリオは何本くらいが目安ですか?

本数の絶対値より層の配分で考えてください。ブラウザ経由で実行するシナリオはプロダクト全体で10本から30本、サービス層で実行するシナリオはその5倍から10倍が一つの目安です。全体の実行時間が10分を超え始めたら、本数ではなく層の見直しに着手する合図と捉えるとよいでしょう。数を目標値に設定する運用は避けてください。

BDDを導入すると開発速度は落ちますか?

導入直後の数スプリントは落ちます。シナリオを書く時間、ステップ定義を実装する時間、語彙を揃える議論の時間が上乗せされるためです。効果が出るのは、仕様の問い合わせと手戻りが減り始めてからで、体感としては2か月から3か月後になります。この期間を織り込まずに評価すると、定着前に打ち切る結果になりがちです。

SpecFlowを使っている場合はどうすればよいですか?

Reqnrollへの移行を検討してください。ReqnrollはSpecFlowのオープンソース版コードベースを基に作られており、フィーチャーファイルの書式は共通です。公式ドキュメントによればSpecFlow v4は正式リリースされずプロジェクトも削除されているため、既存資産を維持したまま更新を受け続けるにはReqnrollが現実的な移行先になります。独自プラグインの対応可否だけ先に確認しておくと安全です。

関連記事

資料請求

RELATED POSTS 関連記事