作者在職業生涯早期從大公司跳到一家八人新創,發現公司連一個測試人員都沒有。恐慌之餘,他和另一位程式設計師反而建立了一套出色的測試工具與技術,打造出他合作過的最完善測試的應用程式之一。這段經歷讓他深刻體會到:品質是整個團隊的責任,而非只是測試人員的工作。
本章涵蓋將測試整合到流程中的重要性、測試自動化金字塔、驗收測試驅動開發(ATDD),以及如何償還技術債。
將測試整合到流程中(Integrate Testing into the Process)#
Scrum 團隊將測試視為開發流程的核心部分,而非開發完成後才做的事。正如 W. Edwards Deming 所主張的:「停止依賴大量檢查來達成品質。改善流程,從一開始就將品質建入產品中。」
為什麼最後才測試行不通#
- 難以提升既有產品的品質:在產品已經出貨後再試圖改善品質,既困難又耗時,使用者可能很久都感受不到改善
- 錯誤持續被忽略:只有測試後才知道某個做法是否正確。在此之前,你可能一直在重複同樣的錯誤而不自知。例如 Geoff 花了將近一整個 Sprint 做效能改善,測試後才發現改善幅度微乎其微
- 難以掌握專案狀態:估算一批新功能的工時容易,但估算一個開發了六個月、從未測試過的產品還需要多久才能修完所有 Bug,幾乎不可能
- 錯失回饋機會:Scrum 的一大好處是每個 Sprint 結束都能獲得回饋。如果品質不足以讓人使用,就錯失了寶貴的早期回饋
- 測試更容易被砍掉:排在專案尾聲的工作,在時程壓力下最容易被縮減或取消
內建品質的團隊長什麼樣#
- 採用良好的工程實踐:自動化單元測試、結對程式設計、程式碼審查、持續整合、持續重構。程式碼由團隊共同擁有,任何人發現改善機會都可以行動
- 程式設計師與測試人員之間的交接幾乎看不見:兩者緊密協作,測試人員先建立自動化測試,程式設計師同時開發功能,完成後立即整合
- Sprint 第一天與最後一天的測試活動量應該一樣多:不存在獨立的分析、設計、編碼或測試階段。測試人員從 Sprint 第一天就和程式設計師一樣忙碌
在不同層級進行自動化(Automate at Different Levels)#
有效的測試自動化策略需要在三個不同層級進行,形成所謂的 test automation pyramid(測試自動化金字塔)。

Figure 16.1: The test automation pyramid
底層:Unit Tests#
單元測試是測試自動化策略的基礎,應該佔金字塔的最大部分。優點包括:
- 能精確定位問題(具體到哪一行程式碼)
- 使用與系統相同的語言撰寫,程式設計師最為熟悉
頂層:UI Tests#
UI 測試放在金字塔頂端,因為應該盡量少做。原因:
- 脆弱(Brittle):UI 的微小改動就可能打破大量測試
- 撰寫成本高(Expensive to write):寫出持久有效的 UI 測試需要大量時間
- 執行時間長(Time consuming):有些 UI 測試套件甚至無法在一夜內跑完
中間層:Service Tests#
這是許多組織長期忽略的關鍵層級。Service-level testing 是指繞過 UI,直接測試應用程式的服務(功能)。以一個簡單計算機為例:與其透過 UI 輸入數字、點擊按鈕、比對結果,不如直接呼叫 multiply 和 divide 方法來測試。
沒有 Service Tests,單元測試和 UI 測試之間的缺口只能靠更多的 UI 測試來填補,導致測試套件既昂貴又脆弱。
手動測試的角色#
完全自動化所有測試是不可能的。手動測試應主要作為 exploratory testing(探索性測試)——快速循環「測試規劃 → 測試設計 → 測試執行」,類似 TDD 的「測試 → 編碼 → 重構」節奏。探索性測試除了找 Bug,還能發現遺漏的測試案例和需求。
在 Sprint 內完成自動化#
自動化測試在 Scrum 專案中不是可選的。自動化測試提供了廉價的保險,確保原本正常的功能持續正常運作。

Figure 16.2: The costs and benefits of automating a test over time
Figure 16.2 說明了一個關鍵洞察:自動化的最大效益來自在功能開發的同一個 Sprint 內完成自動化。隨著時間推移,程式碼變動頻率降低,自動化的效益也隨之下降。如果延遲自動化,往往被迫依賴金字塔頂層的 UI 測試,因為此時加入單元測試和 Service Tests 已經困難重重。
Salesforce.com 的成效#
Salesforce.com 在採用 Scrum 九個月後,在測試自動化方面取得了顯著成果:
- 部署人力減少 65%(降至 15 人)
- 上線前最終測試從 2-3 小時人工降為 10 分鐘自動化
- 上線後健全性測試從 3-4 小時人工降為 45 分鐘跑 200+ 個自動化測試
- Patch release 參與人數減少近 80%
- 每次主要發佈節省超過 300 人時
實施驗收測試驅動開發(Do Acceptance Test-Driven Development)#
ATDD(Acceptance Test-Driven Development)讓工作圍繞驗收測試展開。驗收測試記錄了 Sprint 期間關於功能實作的決策,在對話發生時即時撰寫。
ATDD 可視為 TDD 的類比。Lasse Koskela 展示了兩者之間的關係:ATDD 的外圈驅動整體方向(選擇 User Story → 辨識滿意條件 → 實作以通過失敗的驗收測試 → 重構),TDD 的內圈驅動實際編碼(測試 → 編碼 → 重構)。

Figure 16.3: The relationship between acceptance test-driven development and test-driven development
從滿意條件(Conditions of Satisfaction)出發#
理想情況下,Product Owner 在 Sprint Planning Meeting 前就已為高優先級的 User Story 辨識好 Conditions of Satisfaction(COS)。COS 代表 Product Owner 的高層級期望,位於具體驗收測試案例之上一個層級,非常適合用來驅動 ATDD 流程。
以 COS 開始一個 Sprint,能讓團隊持續聚焦在 Product Owner 的目標上,避免偏離方向或鍍金(gold-plating)。
適當的細節層級#
COS 不需要鉅細靡遺。例如,一個股票視覺化 treemap 功能的 COS 可能是:
- 矩形應盡可能接近正方形,長短邊比例目標為 1.1
- 系統必須在規劃的硬體上每秒生成五個指定複雜度的 treemap
- 支援單一 treemap 中最多 5,000 個項目
- 支援單一 treemap 中最多 500 個群組

Figure 16.4: A tree map in which rectangle size represents market value
測試人員會將這些高層級的 COS 轉化為具體的測試案例,包括 Product Owner 未明確說明但隱含的測試(例如 treemap 即使只有一筆資料也應正確呈現)。
ATDD 的好處#
- 讓團隊持續聚焦於 Product Owner 的目標
- 及早辨識滿意條件,幫助團隊避免走錯方向
- 促進測試人員與開發人員之間的早期溝通
償還技術債(Pay Off Technical Debt)#
Technical debt(技術債)是 Ward Cunningham 提出的概念,指在設計不良、程式碼品質不佳或未完成的工作上持續開發所帶來的額外成本。Cunningham 警告:
「每一分鐘花在不夠正確的程式碼上,都是在支付那筆債的利息。整個工程組織可能會在未整合實作的債務負擔下停擺。」
技術債有時是有意識的取捨——「首次出貨的程式碼就像舉債」——只要迅速償還就沒問題。但如果不及時償還,利息會不斷累積。
技術債的形式多種多樣:導致應用程式崩潰的資料庫異常資料、任何程式設計師碰了就壞的脆弱程式碼,甚至是稍微過時的語言版本或工具——這些遲早都需要處理。
分三步驟償還測試債務#
對於過度依賴手動測試的團隊(最常見的技術債形式之一),可以遵循三步驟流程:

Figure 16.5: The three steps to paying down the cost of manual testing
第一步:止血(Stop the Bleeding)
首要之務是阻止情況惡化。找出容易自動化且能節省大量手動工作的測試(low-hanging fruit)。Brian Marick 指出,真正的低懸果實往往不是自動化測試執行本身,而是自動化其他測試任務,如填充資料庫或自動導航到測試頁面——雖然手動測試數量不變,但大幅縮減了每次的執行時間。
同時,團隊成員也在積累自動化測試的技能,配置測試伺服器和工具。
第二步:保持現狀(Stay Current)
止血之後,情況不再逐 Sprint 惡化。此時團隊要學會為當前 Sprint 新增的功能撰寫自動化測試,確保不再累積新的債務。在同一個 Sprint 內完成自動化是新技能,需要時間適應。
第三步:追趕(Catch Up)
最終,團隊開始清理歷史累積的測試債務。作者表示他不在乎下降線的速度有多快,只要它持續朝正確方向移動即可——最重要的是前兩步。
品質是團隊的責任(Quality Is a Team Effort)#
重視品質能帶來巨大的成效。Salesforce.com 在採用 Scrum 九個月後,Steve Greene 表示公司已經節省了「每次主要發佈超過 300 人時,以及所有 patch release 生命週期中更多的時間」,現在可以將更多時間投入功能、自動化和設計。
這些成果並非特例,任何認真投入的 Scrum 團隊都能達成。但前提是:
- 品質不能只推給測試人員
- 將測試整合到流程中、學習在 Scrum 的嚴格時間框架內應用新技能、償還技術債——這些都是整個團隊的責任
- 好的 Scrum 團隊會持續關注自身的測試實踐,時刻尋找改善的機會