Behavior-Driven Development(BDD)は、システムの動作を自然言語で記述することでTDDを拡張する開発手法です。BDDシナリオはGiven-When-Then形式で記述され、開発者とビジネスアナリストの両方が理解できます。Cucumber(2024)によると、BDDは顧客の要件と実装のギャップを解消し、仕様を実行可能なテストに変換します。
重要なポイント
Behavior-Driven Developmentは、2006年にDan Northがテスト記述の問題に対する回答として提案したTDDの進化形です。TDDでは開発者がテストを書きますが、“何をテストすべきか”という問いは未解決のままでした。BDDはこの問題を、コードのテストからシステムの動作記述へ焦点を移すことで解決します。
BDDの重要な革新は、プロジェクトの全参加者に共通の共通言語を提供することです。開発者、テスター、アナリスト、顧客が統一された言語でシナリオを議論し、それが同時に実行可能なテストとなります。これにより、要件がアナリストから開発者に伝わる過程で意味が失われる古典的な“伝言ゲーム”問題を解消します。
Dan Northは2006年にブログThinkCodeの記事「Introducing BDD」でBDDを提唱しました。彼はTDDのテスト名が実装の用語(「testAddUser」)で記述されることが多く、振る舞いの用語(「user should be able to register with email」)ではないことに気づきました。BDDは「test」を「should」に、「assert」を「expect」に置き換え、ユーザーにとっての価値に焦点を当てました。
Cambridge Universityの調査(2021)によると、BDDシナリオを顧客とのコミュニケーションに使用するプロジェクトは、テキスト文書による従来の仕様と比較して、要件のエラーが35%減少します。実行可能なシナリオは曖昧な表現を許しません — 各Given-When-Thenは実行されるか、されないかのどちらかです。
Gherkinは、CucumberやSpecFlowフレームワークが動作シナリオの記述に使用するドメイン特化言語です。Gherkinはインデントとキーワードを使用してシナリオを構造化し、技術的背景のない人でも読めるようにします。
Feature: Login
Scenario: Successful login with valid credentials
Given the user is on the login screen
When they enter valid username and password
Then they should see the home screen
Gherkinはいくつかの基本的なキーワードを定義しています。Featureは機能を、Scenarioは具体的なシナリオを、Givenは前提条件を、Whenはアクションを、Thenは期待される結果を記述します。さらにAndとButは複数の条件を結合するために使用されます。
Gherkinファイルの拡張子は.featureで、Androidプロジェクトではsrc/test/resources/features/ディレクトリに保存されます。各ファイルはFeatureの説明で始まり、その後に1つ以上のScenarioが続きます。パラメータ化にはScenario OutlineとExamplesテーブルを使用します — これにより同じシナリオを異なるデータで実行できます。
Feature: Calculator
Scenario Outline: Addition of two numbers
Given the calculator is running
When I add <a> and <b>
Then the result should be <result>
Examples:
| a | b | result |
| 2 | 3 | 5 |
| 0 | 0 | 0 |
| -1| 1 | 0 |
Given-When-Thenは、BDDがドメイン駆動設計から取り入れたシナリオ記述の構造的パターンです。各シナリオは前提条件、アクション、期待される結果の3つの部分で構成されます。この形式はユニットテストのArrange-Act-Assertに自然に対応しますが、ビジネスが理解できる言語を使用します。
Givenブロックは、シナリオ開始前のシステムの状態を記述します:存在するデータ、アクティブなコンポーネント、アプリケーションの動作モード。モバイルコンテキストでは、「ユーザーがログインしている」「カートが空ではない」「デバイスがオフラインモードである」などです。
Whenブロックは、ユーザーまたはシステムによって開始されるイベントを記述します:ボタン押下、プッシュ通知の受信、サーバー応答。モバイルアプリでは、これはViewModelメソッドの呼び出しやUI要素のタップに対応することが多いです。
Thenブロックは、期待される状態変化を記述します:画面遷移、API呼び出し、データベース更新。Thenのチェックは測定可能で明確でなければなりません — それらは実行可能コードのアサーションになります。
BDDとTDDはよく混同されますが、異なるレベルの技術です。TDDはコードレベルの設計技法です:「実装の書き方」。BDDは要件レベルの仕様技法です:「システムがすべきこと」。
| 基準 | TDD | BDD |
|---|---|---|
| 焦点 | API設計 | システムの動作 |
| 言語 | コード(JUnit、XCTest) | 自然言語(Gherkin) |
| 対象 | 開発者 | チーム全体+顧客 |
| レベル | ユニットテスト | 受け入れ/統合テスト |
| 結果 | コードでカバーされたAPI | 実行可能な仕様 |
最も優れたモバイルプロジェクトは、個別クラスレベル(ドメイン層)でTDDを、シナリオレベル(機能層)でBDDを使用します。これにより二重のカバレッジが得られます:TDDは実装の正確性を保証し、BDDは要件理解の正確性を保証します。Googleは社内プラクティスでAndroidアプリにTDDとBDDの組み合わせを使用しており、Android Testingドキュメント(2024)に記載されています。
BDDエコシステムには、すべての主要モバイル開発プラットフォームと言語向けのフレームワークが含まれています。ツールの選択は、技術スタックと自動化のレベルによって異なります。
Cucumberは、Gherkinシナリオで動作する最も人気のあるBDDフレームワークです。Androidプロジェクトではio.cucumber:cucumber-androidライブラリを使用し、EspressoやCompose TestなどのUIテストツールと統合します。CucumberはKotlinとJavaの両方をサポートしており、両方の言語を使用するスタジオにとって汎用的な選択肢です。
SpecFlowは、Xamarin.Formsや.NET MAUIプロジェクトで使用される.NETエコシステム向けのBDDフレームワークです。SpecFlowはNUnitやxUnitと統合し、Step definitionsはC#で記述します。モバイルプロジェクトでは、SpecFlowにより共通のコードベースでAndroid版とiOS版のアプリ間でシナリオを再利用できます。
SwiftでのiOS開発には、BDDフレームワークQuickとNimbleがあります。Quickはdescribe/itスタイルのシナリオ記述DSLを提供し、Nimbleは読みやすい構文のマッチャーを提供します。これらのフレームワークはGherkinを直接使用しませんが、BDDの原則を実装しています:チーム全体が理解できる言語での動作記述です。
AndroidプロジェクトにおけるBDDの完全な例を見てみましょう:注文チェックアウトのシナリオです。最初にGherkinシナリオを書き、次にKotlinでStep definitionsを作成します。
BDD手法はthree amigosの会議に基づいています — 開発者、テスター、アナリストの3つの役割です。彼らは開発開始前に共同でシナリオを作成し、要件の共通理解を確定します。3人の参加者のいずれかがシナリオを通過できない場合、要件は曖昧に定式化されています。このプラクティスは「Discovery: Explore Behaviour Using Examples」(Gáspár & North、2021)に記載されており、成熟したチームのBDDプロセスに必須の部分です。
Feature: Order Checkout
Scenario: Apply promo code to cart
Given the user has items in the cart
And the total amount is $100
When they apply promo code "WELCOME10"
Then the discount should be $10
And the final total should be $90
Step definitionsは、Gherkinシナリオをテスト実装に結び付けるコードです。各ステップは、Gherkinのキーワードに対応するアノテーションを持つメソッドです。
class CheckoutSteps {
private val cart = Cart()
private val checkout = CheckoutUseCase()
fun `user has items in the cart`() {
cart.addItem(Item("Phone", 100.0))
}
fun `apply promo code`(code: String) {
checkout.applyPromo(cart, code)
}
fun `discount should be`(expected: Double) {
Assertions.assertEquals(expected, checkout.getDiscount())
}
fun `final total should be`(expected: Double) {
Assertions.assertEquals(expected, checkout.getTotal())
}
}
AndroidプロジェクトでBDDテストを実行するには、CucumberAndroidJUnitRunnerを使用します。これはリソース内の.featureファイルをスキャンし、正規表現で対応するStep definitionsを見つけ、通常のインストルメンテーションテストとしてシナリオを実行します。結果は顧客が理解できるHTMLレポートにフォーマットされます。
// build.gradle.kts
dependencies {
androidTestImplementation("io.cucumber:cucumber-android:7.18.0")
androidTestImplementation("io.cucumber:cucumber-junit:7.18.0")
}
// CucumberOptionsアノテーション
@RunWith(Cucumber::class)
@CucumberOptions(features = "features", glue = ["com.app.steps"])
class CucumberTestRunner
BDDをモバイル開発に導入するには、いくつかの実践的な困難が伴います。これらの問題を認識することで、チームは失望を回避し、持続可能なBDDプロセスを構築できます。
主な問題は、Gherkinシナリオとプロダクションコードの非同期です。開発者がStep definitionsを更新せずにAPIを変更すると、.featureファイルが実装と一致しなくなります。解決策は、CI/CDパイプラインでBDDテストを実行し、マージリクエストにグリーンステータスを要求することです。“ゲーティングメカニズムとしてのBDD”のプラクティスはCucumberドキュメント(2024)に記載されており、業界標準です。
CucumberのBDDシナリオは、Androidデバイスまたはエミュレータ上でインストルメンテーションテストとして実行されます。これはJVM上の通常のユニットテストよりも10〜50倍遅くなります。大規模なAndroidアプリケーションでは、1回の受け入れテストに20〜30分かかる場合があります。BDDテストを別のCIジョブに分離し、夜間に実行し、ユニットテストはプッシュごとに実行することを推奨します。この戦略は、フィードバックの速度とシナリオカバレッジのバランスを取ります。
BDDへの移行には、開発者だけでなくアナリストやテスターのトレーニングも必要です。Gherkinはシンプルな言語ですが、優れたシナリオを作成するには練習が必要です。初心者の典型的な間違いとして、長すぎるシナリオ(10ステップ以上)、Given-When-Thenの混在、ビジネスシナリオでの技術用語の使用があります。BDD Academy(2024)によると、チームがBDDシナリオ作成に熟達するまでには平均4〜6スプリントかかります。
よくある質問
TDDはユニットテストを通じたAPI設計に焦点を当て、BDDは自然言語のシナリオを通じたシステム動作の記述に焦点を当てます。BDDはTDDを拡張し、非技術的な参加者も含むチーム全体の共通言語を追加します。
モバイル開発向けの主要BDDフレームワーク:Cucumber(Android、iOS)、SpecFlow(Xamarin、.NET MAUI)、Quick/Nimble(iOS、Swift)。Cucumberはすべての主要プラットフォームをサポートする最も汎用的な選択肢です。
GherkinはBDDの主要言語ですが、唯一のものではありません。iOSフレームワークQuickはSwift独自のDSLを使用します。ただし、Gherkinはクロスプラットフォームプロジェクトのデファクトスタンダードであるため、習得をお勧めします。
BDDはテキスト仕様を実行可能なシナリオに置き換えます。顧客は開発開始前にシナリオを確認でき、実装後には合格を示すグリーンレポートを確認できます。これによりフィードバックサイクルが短縮され、要件のエラー数が減少します。
はい、BDDは手法であり、ツールではありません。BDDの原則は、テストに「条件XのときにYをすべき」というスタイルの名前を付けることで、任意のテストフレームワークを通じて実装できます。ただし、CucumberとGherkinはチーム全体に一貫した言語を提供します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。