BDDへ — 「振る舞い」に着目したテストの語彙革命
ThoughtWorksでTDDの実践とコーチングに携わっていたDan Northは、初心者が繰り返し抱く迷いの根が「テスト」という言葉そのものにあると気づいた。2003年のJBehaveに始まり、2006年の論文でBDDを体系化、RSpecとCucumber/Gherkinを通じて「実行可能な仕様」を書く文化が広まった。Given-When-Thenという語彙が業界横断で定着するまでの経緯と、その功罪を辿る。
ビヘイビア駆動開発(Behaviour-Driven Development, BDD)は、テスト駆動開発(TDD)の実践から生まれた、しかしTDDとは似て非なる方法論である。
生みの親であるDan North(正式名Daniel Terhorst-North)は、TDDを教える中で繰り返し同じ疑問にぶつかった。「どこまでテストすればいいのか」「これはテストと呼ぶべきものなのか」「何を最初にテストすべきか」——これらは技術的な問題ではなく、「テスト(test)」という言葉が引き起こす語彙上の混乱だとNorthは気づいた。この気づきから、「テスト」ではなく「振る舞い(behaviour)」を語彙の中心に据える新しい実践が生まれた。それがBDDである。BDDはやがてJBehave、RSpec、Cucumberという3つの重要なツールを通じて具体化され、Gherkin記法とGiven-When-Thenという構造化された自然言語で「実行可能な仕様(executable specification)」を書く文化を生み出した。
TDDの「test」という語彙が生む誤解
2000年代前半、NorthはThoughtWorksでTDDの実践とコーチングに携わっていた。彼が繰り返し観察したのは、TDD初心者が抱く根源的な迷いだった。
- テストメソッド名を
testXxxと書くべきか、何をテストしていると考えるべきか分からない - 「単体テスト」と「受け入れテスト」の境界が曖昧
- 「テストファースト」と言われても、まだ存在しない機能に対して何を検証すればよいのか分からない
- テストが増えるほど「テストのためのテスト」に見えてしまい、ビジネス価値との接続を見失う
Northはこれらの問題の根っこが技術ではなく言葉にあると考えた。「テスト」という言葉は「検証」を連想させ、「これから何を作ろうとしているのか」という設計・仕様の側面を覆い隠してしまう。そこでNorthは、テストコードの命名をtest〜ではなくshould〜(〜すべきである)に置き換えることを提案した。これにより焦点が「検証」から「期待される振る舞いの記述」へと移る。
JBehaveの誕生(2003年)
2003年末、NorthはJUnitの代替として、テストという語彙を一切排除したフレームワークJBehaveを書き始めた。JBehaveはJavaの単体テストの文法を「振る舞いの仕様(behaviour specification)」として書き直すことを狙ったもので、2004年にかけて発展した。この初期の試みには、後にBDDの発展に関わるLiz KeoghやChris Mattsも早い段階から関与している。
2004年末、NorthがChris Mattsに自身の「振る舞い中心の語彙」を説明していたとき、Mattsが「それって分析(analysis)そのものじゃないか」と指摘したエピソードは、BDDが単体テストの技法から要求分析・受け入れ基準の技法へと拡張していく転機として知られている。Mattsはこの流れの中で、ビジネス価値を起点に機能を洗い出すフィーチャーインジェクション(Feature Injection) という手法を考案した。
“Introducing Behaviour-Driven Development”(2006年)
Northは2006年3月、業界誌『Better Software』にBDDを体系的に紹介する論文 “Introducing Behaviour-Driven Development” を発表した。この論文でBDDは次のように整理された。
| TDDの用語 | BDDでの言い換え |
|---|---|
| テストを書く(test) | 振る舞いを記述する(specify behaviour) |
テストメソッド名testXxx |
should〜 / it〜形式の文 |
| 単体テストと受け入れテストの区別が曖昧 | 「開発者向けの振る舞い」と「ビジネス向けの振る舞い」を明確に分離 |
| テストがドキュメントになる(副産物) | 仕様書として最初から書く(一次成果物) |
この論文でGiven-When-Thenという受け入れ基準の記述テンプレートも紹介された。「Given(前提条件)」「When(操作・イベント)」「Then(期待される結果)」という三部構成は、ドメイン駆動設計(DDD)でEric Evansが提唱したユビキタス言語(ubiquitous language)——開発者とドメインエキスパートが同じ語彙を共有すべきという考え方——の影響を強く受けている。
RSpecの誕生と発展
JBehaveがJavaの世界での実験だったのに対し、BDDの思想をRubyの世界で本格的に花開かせたのがRSpecである。
- 2005年 — Steven Bakerが実験としてRSpecを開始。Dave AstelsとAslak Hellesøyが初期の貢献者として参加
- 2006年夏 — David Chelimskyがプロジェクトに参加し、後にリーダーシップを引き継ぐ
- 2007年5月 — RSpec 1.0がリリース。
describeブロックで対象を、itブロックで期待される振る舞いを記述する構文が確立した
describe Order do
it "is invalid when the total is negative" do
order = Order.new(total: -10)
expect(order).not_to be_valid
end
end
このdescribe/it/expectという構文は、「テストケース」ではなく「仕様(spec)」を書くという体験を提供し、BDDの語彙をコードレベルで体現した。2009年には、ChelimskyとAstelsを中心に、Bryan Helmkamp、Dan North、Zach Dennis、Aslak Hellesøyの共著で 『The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends』 が出版され、BDDの実践知が体系化された。
Cucumberの誕生とGherkin記法
RSpecの初期貢献者だったAslak Hellesøyは、自然言語に近い形式で受け入れ基準を書き、それをそのまま実行可能なテストとして動かすツールCucumberを開発した。CucumberはRuby向けにスタートし、後に多言語対応(Cucumber-JVM、SpecFlow[.NET]、behave[Python]など)が広がった。
Cucumberの中核がGherkin記法である。GherkinはGiven-When-Thenの構造をビジネス側の担当者でも読み書きできる自然言語風のテキストとして形式化したものだ。
Feature: Applying a discount coupon
Scenario: A valid coupon is discounted
Given the cart total is 3000 yen
And I have a valid 10% discount coupon
When I apply the coupon
Then the total becomes 2700 yen
このシナリオはそのまま「ステップ定義(step definition)」と呼ばれるコードに紐付けられ、自動テストとして実行される。これにより、ビジネス側が読める仕様書と、実際に動くテストコードが(理論上は)一致した状態を保てるようになった。
BDDフレームワークの多言語展開
Cucumber/Gherkinのモデルは、Ruby以外の言語エコシステムにも急速に広がった。
| 言語・環境 | ツール | 備考 |
|---|---|---|
| Ruby | Cucumber, RSpec | 元祖。GherkinとRSpec風構文の両方が併存 |
| Java / JVM | Cucumber-JVM, JBehave | JBehaveはNorth自身が生んだ源流 |
| .NET | SpecFlow | Gherkinを.NET上で実行、後継はReqnroll |
| Python | behave, pytest-bdd | Gherkin風の.featureファイルをpytestと統合するものも |
| JavaScript | Cucumber.js, jest-cucumber | Jest上でdescribe/itにGherkinのシナリオを流し込む形も普及 |
これらはいずれも「Given-When-Then」という共通の語彙とGherkin風の記法を土台にしており、BDDが特定言語の流行にとどまらず、テスト記法の共通言語として定着したことを示している。
Specification by ExampleとExample Mapping
BDDの実践が広がる中で、「どうやってGiven-When-Thenのシナリオを協働で洗い出すか」という発見(discovery)のプロセス自体を体系化する動きも生まれた。Gojko Adzicは2011年、約50のプロジェクト事例をもとにした著書 『Specification by Example: How Successful Teams Deliver the Right Software』 を出版し、「具体例による仕様化」というBDDに近接する実践知を体系立てた(同書は2012年のJolt Awardを受賞)。
さらに、Cucumber社のMatt Wynneは、ユーザーストーリーをGherkinシナリオに落とし込む前段階として、Example Mappingという軽量なワークショップ手法を考案した。付箋を使い、「ストーリー(黄)」「ルール(青)」「具体例(緑)」「疑問点(赤)」の4色で短時間(25分程度)に整理するこの手法は、Three Amigosの議論を発散させずに具体例へ収束させる実践として広く採用されている。
ユビキタス言語・受け入れ基準・Three Amigos
BDDが単なるテスト技法にとどまらず開発プロセス論として広がった背景には、次のような実践がある。
- ユビキタス言語との接続 — DDDのユビキタス言語と同様、Gherkinのシナリオはビジネス・開発・QAが共有する語彙の器になる
- Three Amigos(三者会議) — 要求を固める際に、ビジネスアナリスト(BA)・開発者(Dev)・テスター(QA)の3者が集まり、Given-When-Thenの形でシナリオを合意形成する慣習。BDDが「テストの自動化技法」ではなく「要求分析・協働の技法」であることを示す典型例である
- 受け入れテスト駆動開発(ATDD)との関係 — ATDDもビジネス側と合意した受け入れ基準からテストを導く点でBDDと重なるが、BDDはそこに「振る舞い」という統一語彙とGherkinという記法を持ち込んだ点が独自性である
BDDの功罪
BDDの普及は多くの現場に「仕様と一致したテスト」という理想をもたらしたが、実践上の弊害も広く指摘されるようになった。
- 過剰なGherkin化 — すべてのテストをGherkinで書こうとした結果、単体テストレベルの些末な検証まで自然言語のオーバーヘッドを背負い、可読性がかえって低下するケースが頻発した
- 二重メンテナンスコスト —
.featureファイル(シナリオ)とステップ定義コードの両方を保守する必要があり、リファクタリング時に同期が崩れやすい - 「自然言語風」の脆さ — 微妙な言い回しの違いでステップ定義がマッチしなくなる、文言の統一が属人化するといった問題
- ビジネス側が実際には読まない — 理想では非エンジニアが
.featureファイルを読み書きするはずが、実際には開発者・QAだけが保守する「テストのための独自DSL」になっている現場も多い - Dan North自身の再考 — Northは後年、BDDの本質は「Given-When-Thenという記法」ではなく「振る舞いに焦点を当てる考え方」だと繰り返し強調し、Gherkinの機械的な適用に警鐘を鳴らしている
現在の位置づけ
現在では、BDDフレームワーク(Cucumber、SpecFlow、behave、Jest-Cucumberなど)はE2E・受け入れテストの層で使われることが多く、単体テストレベルでは「BDDスタイルのアサーション」(describe/it構文を使うが自然言語DSLは使わない、Jest・Mocha・RSpecなど)として、語彙だけがゆるやかに定着している。BDDは「全てをGherkinで書く」運動としては後退しつつも、「テストは仕様であり、振る舞いを記述するものだ」という思想そのものは、xUnit系フレームワークのdescribe/it構文や、契約テスト・受け入れ基準の書き方に深く根を残している。
現場での実務的な落とし所は、おおむね次のように整理できる。
- 受け入れ基準・E2Eレベルの少数の重要シナリオだけをGherkinで書き、ビジネス側との合意形成の道具として使う
- 単体テストレベルでは自然言語DSLを使わず、
describe/itの語彙だけを借りて可読性を上げる - Example MappingのようなDiscoveryワークショップを、Gherkin自動化と切り離して「要求を明確にする会話の道具」として単独で使う
この「協働の技法」と「自動化の技法」を分けて捉える視点こそが、2006年のNorthの問題意識——「テスト」という言葉が引き起こす混乱を「振る舞い」という語彙で解きほぐす——に立ち返る形で、BDDの現在地を最もよく説明している。
この記事から次の記事へ
BDDが「振る舞い」という語彙で解決しようとしたのは、あくまで何を検証するか、どう記述するかという問題だった。だが、テスト対象が依存する他のオブジェクトをどう扱うかという、classicist/mockist論争(前章参照)の中心にあった問いは、依然として残る。次章では、テストダブル(スタブ・モック・フェイク・スパイ)の分類と、モックという技法そのものがどのように発展してきたかを辿る。