9 mins read | 2097 words

Behavior Driven Development (BDD)

前言

在進入細節探討前,先回顧一下以開發者為視角在產品開發生命週期的痛點:

開發者最常遇到的問題不是程式寫不出來,而是寫出與客戶預期不同的東西。

為什麼會有這樣的問題?

在傳統開發流程中,需求從客戶傳遞給 PM,再由 PM 寫成規格書交給開發者,最後由 QA 測試。

在這個資訊鏈條中,每一層都會產生資訊落差,而開發者只能看著 Spec 通靈,結果等到 Demo 時才發現,大家對同一個功能的理解根本不在同一個頻道上。

為什麼需要 BDD

Behavior Driven Development(行為驅動開發),簡稱 BDD,正是為了解決這種「認知誤差」而生的一種開發模式。

BDD 關注的是什麼

BDD 是從 TDD (Test Driven Development) 演進而來的。如果說 TDD 關注的是「這段 Code 跑得對不對(實作正確性)」,那麼 BDD 關注的就是「系統的行為是否符合業務預期(行為正確性)」。

它強調節省無謂的溝通成本,將開發焦點從「如何實作」轉移到「使用者如何使用」,也就是大家常聽到的 User Story。

帶來的好處與價值

  • 共通語言: 使用接近自然語言的語法,讓技術人員與商務人員(PO、客戶)能用同一套語言交流。
  • 活的文件 (Living Documentation): 測試腳本即是規格書。當功能異動時,測試也會同步更新,解決了「規格書寫完就過時」的萬年難題。
  • 減少重工成本: 在寫程式前就透過討論釐清邊界案例(Edge Cases),避免開發完成後才發現邏輯錯誤。

BDD 的核心流程

BDD 通常會被拆成三個步驟:Discovery、Formulation、Automation。

探索 (Discovery)

這是最重要的一步。透過 「三個火槍手」(The Three Amigos) 會議:PO (業務)、Dev (開發)、QA (測試) 共同討論。

但重點不是討論功能,而是透過「具體例子」來了解需求。

例如:

  • 正常情況會怎樣?
  • 邊界條件是什麼?
  • 有沒有例外情境?

這個過程的本質,是把原本抽象的需求,轉成一組可以被討論的「行為案例」。

表述 (Formulation)

當團隊對情境達成共識後,下一步就是把這些案例轉成結構化描述(例如 Gherkin)。

這一步的重點在:讓「大家覺得對」的事情,變成「可以被驗證是否正確」的規則。

一旦規則被明確定義:

  • 開發知道什麼叫完成
  • QA 知道怎麼驗收
  • PM 知道需求是否被滿足

自動化 (Automation)

最後,才是將這些規格連結到自動化測試。

這一步的目的不是「寫測試」,而是:

確保這些行為在未來不會被破壞。

當系統演進時,只要測試失敗,就代表某個既有行為被改變,團隊就能即時發現。

Gherkin 腳本

Gherkin 是 BDD 中最常用的領域特定語言 (DSL),它使用簡單的關鍵字來定義行為邏輯,有點像是 DDD 中的 Ubiquitous Language(通用語言)。

它的真正價值在於「讓需求變成可以被所有人理解、也可以被驗證的語言」。

它透過一組簡單的關鍵字(Given / When / Then),把原本模糊的需求,轉換成具體且可驗證的行為描述。

  • Feature (功能): 描述這個功能的整體目的(通常對應一個 User Story)。
  • Scenario (情境): 一個具體的使用情境,也就是一個「可驗證的例子」。
  • Given (前提): 系統目前處於什麼狀態或擁有什麼條件。
  • When (行為): 使用者觸發了什麼動作或行為。
  • Then (結果): 預期系統會產生什麼結果。

這樣的結構,其實對應的是一個非常直覺的思考方式:

在某個情境下(Given),當使用者做了某件事(When),系統應該有什麼反應(Then)

Terminal window
Feature: 提款功能
為了能夠領取現金
作為一名持卡人
我想要在提款機提取帳戶餘額
Scenario: 餘額充足時取款成功
Given 我的帳戶餘額有 5000
And 我的提款卡是有效的
When 我選擇提取 2000
Then 提款機應吐出 2000 元現金
And 我的帳戶餘額應更新為 3000
Scenario: 餘額不足時應顯示錯誤
Given 我的帳戶餘額只有 500
When 我選擇提取 1000
Then 提款機不應吐出錢
And 系統應顯示「餘額不足」的提示訊息

當這些腳本被用來做自動化測試時,它同時也是規格;當需求改變時,只要更新這些情境,測試與文件就會同步更新。

應該如何推動

首先,推動 BDD 不建議從工具或框架開始,而是先從「讓團隊意識到溝通成本的代價」開始。

與其抽象地介紹流程,不如回到團隊最近一次因需求理解錯誤而重工的案例,具體拆解時間成本:開發花了幾天、驗收失敗後修正又花了幾天、QA 重測又花了多久。

當大家開始意識到「短短一段沒講清楚的需求,實際上消耗了整個團隊數天的產能」,才會開始認真看待 BDD 想解決的問題。本質上,BDD 不是增加流程,而是把「本來就會發生的成本」提前用更便宜的方式處理。

接著,在實際導入時,不需要一開始就導入完整的 Gherkin 或自動化測試,而是先在 Sprint Planning 或需求討論階段,刻意放慢節奏,專注在「把需求講清楚」。

選一個最模糊、最容易產生歧義的 User Story,讓 PM、開發與 QA 嘗試用「具體情境」來描述它,例如:正常情況會發生什麼?如果輸入錯誤?如果系統異常?如果使用者行為超出預期?

這個過程會自然暴露出大量原本沒被定義的邊界條件,而這些正是未來最容易變成 Bug 的地方。當團隊開始習慣用「例子」而不是抽象描述來溝通時,其實就已經在實踐 BDD 的 Discovery 階段了。

當這種對話模式逐漸穩定後,再把這些共識轉化為結構化的描述,例如 Given / When / Then。

這一步的重點不是語法本身,而是讓這些情境成為一種「團隊共識的合約」:只要系統行為符合這些情境,就代表功能完成;反之,如果驗收時出現不在情境內的要求,也能有依據回到討論本身,而不是陷入各說各話。

這種做法會明顯降低驗收階段的摩擦,因為「對與錯」不再是主觀判斷,而是是否符合既定行為。

最後,才是考慮是否將這些情境串接到自動化測試工具。

很多團隊在這一步會卡住,是因為一開始就把 BDD 等同於 Cucumber 或測試框架,導致導入成本過高而失敗。

不過更有效的做法應該是先讓團隊習慣「用例子對齊需求」,再逐步將高價值、重複驗證成本高的情境轉為自動化測試。

這樣不僅降低導入阻力,也能確保自動化測試覆蓋的是「真正重要的業務行為」,而不是流於形式的腳本。

簡單來說,BDD 的推動順序應該是:先改變對話方式,再沉澱為規格,最後才是工具化。如果順序顛倒,很容易變成只是多寫了一層測試語法,卻沒有解決最核心的溝通問題。

BDD 常見誤區

許多人在使用 BDD 時會陷入一個誤區:為了自動化而寫 Given/When/Then。

但 BDD 的核心價值在於那一場「三個火槍手」的會議。工具(Cucumber, Gherkin)只是輔助,真正的魔法發生在當工程師問出:「如果使用者在提款時斷網會怎樣?」而 PO 拍案說:「好問題,我們來定義這個行為」的那一刻。

這才是 BDD 真正能讓開發團隊擺脫「做白工」循環的關鍵。

Licensed under CC BY-SA 4.0

Unless otherwise noted, content on this site is licensed under CC BY-SA 4.0. You are free to share and adapt with attribution.

認識 Test-Driven Development (TDD)
自從踏入軟體開發職場後,我最早認識到的開發流程之一就是 TDD,我也認為他應該是每位軟體開發者都應該知道的開發流程,即使在實務上並非所有專案或情境都適合採用,但我覺得能有 TDD 的概念也很棒。
8mins read
關於 Domain-Driven Design (DDD)
自數位轉型年代開始,軟體開發領域開始流行 DDD 一詞的說法,所謂領域驅動設計 Domain-Driven Design (DDD) 是一種軟體設計方法論,核心目的是讓程式設計與商業邏輯緊密對齊,以便未來因應商業需求變更。
9mins read