第 1 章提到,「快速的部署管線」是流暢交付的重要架構需求,而部署管線的速度同時取決於兩個品質屬性:可測試性(testability) 與可部署性(deployability)。本節聚焦可測試性。
可測試性反映「驗證一個變更是否可釋出」的速度與便利度。
開發者與部署管線都要做這個驗證:edit-test-analyze 迴圈的速度直接決定生產力,部署管線的速度決定回饋多快。容易撰寫 + 執行迅速 是兩個必要條件。
可測試性的場景#
幾項通用要求:
- 變更時開發者能輕易寫出自動化測試驗證該變更。
- edit-test-analyze 迴圈中執行的測試要快。
- pre-commit 測試(在 git push 前執行)也要快。
- 部署管線的前置時間(主要由等待時間 + 測試執行時間組成)應控制在某個 X 分鐘內。
具體場景:
- Orders team 開發者修改 Order Management 的業務規則,在 IntelliJ IDEA 跑測試 2 秒內完成;團隊回報為自家子領域寫測試很直接。
- 開發者準備 git push,跑 pre-commit 測試在 1 分鐘內完成。
- 開發者 git push 後,部署管線觸發,10 分鐘內完成測試,告知變更可釋出。
高可測試性架構的三個維度#
- Automatable(可自動化):必須用自動化測試,而非人工測試。
- Fast running tests(快速執行):讓回饋盡可能快。
- Running tests locally(本地執行):讓開發者在自己機器上跑測試,不需仰賴遠端測試環境。

Figure 5.13: Fast flow requires an architecture testable via fast running automated tests that run locally on a developer's laptop
可自動化:用自動化測試驗證#
人工測試太慢、太容易出錯,難以承載流暢交付的變更量;尤其由獨立 QA team 處理時,會大幅拖慢開發。
「Design for testability」(以可測試性為導向的設計):軟體設計本身應讓測試容易寫。
三個關鍵設計策略:
- 小、鬆設計期耦合的元素:簡單元素需要的測試更少更單純;穩定 API 也讓測試(本身就是 API client)不必頻繁更動。
- 消除或限制非確定性:應用要可驗證就必須是確定性的(deterministic);非確定性程式碼會讓測試 flakey,最好把它隔離到獨立元件,搭配獨立(可能 flakey)的部署管線。
- 依賴注入(dependency injection)+ 函數式風格:DI 讓測試能注入 test double 取代麻煩的依賴;函數式風格(無副作用、無依賴的純函式)讓測試只需呼叫函式並檢查回傳值,根本不需 test double。
執行快:重測「真正受影響的子專案」#
大型應用整套測試太慢,改為只測受變更影響的子專案——包括含被修改檔案的子專案,以及那些依賴它的子專案。

Figure 5.14: Reduce validation time by retesting only the build projects affected by the change
加速手段:
- 增量建置(incremental builds):Gradle 等工具僅在子專案的 source 或 test classpath 改變時才重跑測試。
- 鬆建置期耦合:client 應依賴穩定的 API 子專案,而非常變動的 implementation 子專案,實作改動時 client 不必重測。

Figure 5.15: A subdomain's clients should depend on the more stable API build project, not the less stable implementation
- 鬆設計期耦合 + 高內聚:讓變更局限在少數子專案,需執行的測試套件數自然下降。
- Design for testability:DI 與函數式風格讓你能用快速的單元測試取代沉重的整合測試(避免起資料庫、message broker)。
- 多元件架構:變更局限在單一元件時,只跑該元件的測試;依賴可用 test double 模擬;每個元件有自己的部署管線,等待時間更短。
不要靠「平行化」與「叢集化」當主軸——它們昂貴又複雜,本地環境也未必有對應資源。先把建置期耦合與設計期耦合修好,這通常已經能把測試時間壓得很低。
本地執行:避免遠端測試環境#
《Accelerate》研究指出,「能在本地測試」是高效能組織的關鍵能力之一。
遠端測試環境會延長 edit-test-analyze 迴圈,還要花心力把可能不穩定的共用環境拉回已知狀態。
為什麼有時做不到?#
應用太大或依賴太多基礎設施服務時,開發者筆電可能跑不動或跑不快。
兩種因應方式#
- 配備更強的筆電:例如 16 核、128 GB 記憶體的 MacBook。或使用雲端開發環境(GitPod、GitHub Codespaces)讓 IDE 連到 EC2 上的開發環境。但 CFO 不會開心,而且即使有大型 EC2,你的應用也可能跑不起整套。
- 多元件架構:更實用的做法。重點是讓開發者只跑自己負責的那個元件,而非整個應用。
- 範例:Orders team 開發者只啟動 Order Service 與其資料庫、message broker;像 Customer Service 這類依賴用 test double 模擬(例如 consumer-driven contract testing,第 16 章詳述)。

Figure 5.16: A multi-component architecture lets a developer work efficiently by running only their component locally
不得不用遠端環境的場景#
- 應用實作 webhook,需被第三方應用呼叫——把這類流量導到開發者筆電通常不可行。
- 多元件架構也能緩解:把無法本地測試的部分隔離成獨立元件,由其專屬部署管線在特殊測試環境驗證,其餘元件仍能本地測試。
可測試性同時支撐兩件事:部署管線的速度與本地開發的速度。把這個品質屬性顧好,後續的可部署性才能真正發揮作用。