在軟體開發的領域中,利益相關者所想像的與開發人員所建構的之間的差距,往往是造成重大摩擦的根源。需求的模糊性導致重做、發布延遲以及團隊的挫敗。為了彌合這道鴻溝,團隊需要一種精確、易讀且可執行的共通語言。其中最有效的技術之一就是Given When Then語法。這種方法能將模糊的使用者故事轉化為明確的行為規格。
當正確應用時,此方法不僅僅是一種撰寫練習;它會成為業務、設計團隊與工程之間的合約。它確保每項交付的功能都符合預期的價值。本指南探討了使用 Given When Then 有效指定使用者故事行為的機制、優點與最佳實務。

🧠 理解核心結構
Given When Then 模式是行為驅動開發(BDD)的基本組成部分。它以模仿自然語言的方式來組織驗收標準,使非技術利益相關者也能理解,同時仍具備足夠的細節以支援自動化測試。模式中的每一部分都具有明確的用途,用來定義情境的生命周期。
- Given:建立初始情境或狀態。透過描述行動發生前所需的先決條件,來設定場景。
- When:描述觸發行為的特定事件或動作。這就是輸入或刺激。
- Then:定義可觀察的結果或輸出。驗證系統在行動後是否按預期運作。
透過分離情境、行動與結果,團隊能夠隔離變數,並精確理解系統中哪一部分負責特定行為。這種模組化設計降低了複雜度,使除錯變得更容易。
📝 拆解各個組件
🏗️ 「Given」情境
Given 步驟經常被忽略,但對於建立正確環境至關重要。它不應描述行動本身,而應描述系統的狀態。一個撰寫良好的 Given 步驟應回答這個問題:「在開始之前,什麼必須為真?」
撰寫此部分時需考慮細節:
- 狀態 vs. 資料:區分應用程式的狀態(例如:使用者已登入)與存在的資料(例如:使用者帳戶餘額為 100 美元)。
- 先決條件:列出所有必要的先決條件。如果因資金不足導致付款失敗,Given 步驟必須確保確實檢查了餘額。
- 可讀性:保持陳述語氣。避免使用命令式語句,例如「按一下按鈕」。應改用「使用者位於儀表板上」。
當 Given 步驟模糊時,測試會不可預測地失敗。如果系統狀態未明確定義,自動化測試可能會在與預期不同的環境中執行,導致錯誤的負面結果。
🚀 「When」觸發
When 步驟代表互動。這是使用者或系統啟動變更的時刻。這應是一個單一、原子性的動作。如果將多個動作合併到一個 When 步驟中,將難以釐清流程中哪一部分導致了失敗。
When 範圍的關鍵考量包括:
- 單一責任:每個情境只專注於一個事件。若需測試一連串事件,應考慮將其拆分為獨立的情境,或使用情境範本(Scenario Outlines)。
- 使用者意圖:從使用者或系統邊界的觀點來描述動作。「使用者提交表單」比「提交按鈕被點擊」更佳。
- 時機:避免使用「很快」或「稍後」等模糊用語。明確指出觸發條件。
📝 「然後」的結果
「然後」步驟是驗證機制,用以確認系統對「當」步驟的回應是否正確。這正是驗證價值主張的時刻。
有效的「然後」步驟應具備:
- 可觀察:驗證可見或可測量的事物。檢查使用者介面元素、資料庫記錄或 API 回應。
- 避免實作細節:專注於結果,而非內部邏輯。「確認訊息出現」比「資料庫 ID 增加」更佳。
- 涵蓋成功與失敗:確保明確說明動作失敗時的後果。「然後顯示錯誤訊息」與「然後下訂單」同等重要。
📊 透過結構化資料提升清晰度
為了提升可讀性並減少重複,團隊經常在規格中使用表格。當需以不同資料輸入測試相同行為的多種變異時,這特別有用。
| 情境類型 | 重點 | 範例 |
|---|---|---|
| 順利路徑 | 標準成功流程 | 給定有效的憑證,當嘗試登入時,則顯示儀表板。 |
| 邊界案例 | 邊界條件 | 給定長度為 8 個字元的密碼,當請求重設時,則接受該密碼。 |
| 負面路徑 | 錯誤處理 | 給定已過期的會話,當請求存取時,則導向登入頁面。 |
使用此結構可讓利害關係人快速瀏覽需求,並在不閱讀冗長段落的情況下理解覆蓋範圍。
🚫 應避免的常見陷阱
即使擁有穩固的框架,團隊仍經常引入會削弱規格有效性的錯誤。及早識別這些陷阱,可確保文件的長期有效性。
❌ 混合關注點
一個常見的錯誤是在同一個步驟中將商業規則與技術限制混合起來。例如,說「假設資料庫已連接」會將基礎設施與行為混為一談。系統應假設連接性由較低層級處理。專注於商業情境。
❌ 模糊的動詞
像「處理」、「處理」或「管理」這樣的詞語過於籠統,無法定義結果。不要說「系統處理訂單」,而應說「發送訂單確認郵件」。明確性可以消除理解上的錯誤。
❌ 情境過多
雖然細節是好的,但過度規範會帶來維護上的負擔。如果一個情境有二十個「Given」步驟,很可能是在嘗試做太多事情。應將其拆分為更小、可重用的上下文模塊。
❌ 技術耦合
不要撰寫依賴特定實作細節(如類別名稱或資料庫結構)的情境。這些細節經常變動,會無謂地導致測試失敗。應專注於可觀察的行為。
👥 協作動態
Given When Then 的力量在於它促進的協作。它不僅是一種文件格式,更是促進團隊對齊的輔助工具。
- 產品負責人: 他們根據商業價值定義「然後」的結果。確保行為符合使用者需求。
- 開發人員: 他們釐清「給定」的上下文,以理解前置條件和依賴關係。
- 測試專員: 他們驗證「當」的動作,以確保系統正確回應,且邊界情況已涵蓋。
這種共同理解減少了對孤立文檔的依賴。當規格以共享格式撰寫時,每個人都能貢獻於需求的品質。
🔁 從規格到自動化
這種語法的主要優勢之一是它能直接映射到自動化測試框架。雖然具體工具各不相同,但邏輯結構保持一致。
當情境被清楚地撰寫時,可以幾乎無摩擦地轉換為可執行的程式碼:
- 步驟定義:每個「給定」、「當」或「然後」的短語都可以對應到測試套件中的函數。
- 可重用性:常見的上下文(如「使用者已登入」)只需定義一次,即可在多個情境中重複使用。
- 回歸測試的安全性:隨著應用程式不斷演進,這些情境扮演著安全網的角色,確保新程式碼不會破壞現有的行為。
這種整合創造了一個單一的真相來源。接受標準就是測試,而測試就是接受標準。這種對齊確保了被測試的內容正是各方所同意的內容。
💎 實際範例
為了說明標準需求與行為規格之間的差異,讓我們來看一個具體功能:密碼重設請求。
❌ 模糊的規格
「使用者應能在忘記密碼時重設密碼。系統應發送電子郵件。」
這留下了過多的解釋空間。如果電子郵件地址無效會怎麼樣?如果使用者不存在會怎麼樣?電子郵件的發送時機未明確規定。
✅ Given When Then 規範
情境:請求重設密碼
給定該使用者已註冊電子郵件「[email protected]」的帳戶
當他們使用該電子郵件地址提交重設表單
則螢幕上會顯示確認訊息
並且重設連結會發送到「[email protected]」
情境:使用未知電子郵件重設密碼
給定沒有與「[email protected]」關聯的帳戶
當他們提交重設表單
則會顯示通用的成功訊息
並且不會將電子郵件發送到所提供的地址
這些範例清楚展示了如何明確處理安全性與易用性。第二種情境透過不揭露帳戶是否存在來保護使用者隱私,這是一項關鍵的安全考量。
🛡️ 資料驅動的情境
通常,單一行為適用於多個資料集。為每種變體撰寫獨立的情境會變得重複。解決方案是使用情境範本。
此結構允許您一次定義流程,並以不同的資料點填入。
| 輸入金額 | 預期餘額 | 狀態 |
|---|---|---|
| $50 | $150 | 成功 |
| $-10 | $100 | 錯誤 |
| $1000 | $1000 | 達到限制 |
透過使用佔位符定義流程,您可以在保持可讀性的同時確保全面覆蓋。此方法可減少重複,並使更新更為容易。若流程變更,您只需更新範本,而非五十個獨立的場景。
📏 維護與演進
規格並非靜態的產物。隨著產品的成熟,它們必須持續演進。定期審查是必要的,以確保「給定 當時 然後」步驟保持準確。
維護的最佳實務包括:
- 重構步驟: 如果某一步驟變得過於複雜,請將其重構為更小且有意義的單元。
- 棄用: 移除不再反映當前業務邏輯的場景。
- 版本控制: 跟蹤場景的變更,以了解需求如何隨時間演變。
投入時間維護這些規格,將在減少錯誤數量和加快新成員融入團隊方面帶來回報。新開發人員可以閱讀場景來理解系統行為,而無需深入代碼中查找。
💡 對規格的最終思考
撰寫清晰的規格是一項需要練習與細節關注的專業技能。『給定 當時 然後』模式為此專業提供了穩固的框架。它迫使團隊在撰寫程式碼之前,仔細思考其功能的影響。
透過專注於情境、動作與結果,您將創造出一份活生生的文件,推動開發與測試。它使團隊圍繞共同的「完成定義」達成一致。這種一致性是高品質軟體交付的基礎。
請記住,目標是溝通。如果利益相關者無法理解場景,那它就尚未準備好。運用此結構促進對話、釐清期望,並打造真正符合使用者需求的軟體。











