品質是團隊的責任,不只是測試的責任。
品質的定義與責任#
品質不是測出來的,而是設計和開發出來的。品質保障是整個團隊的責任,不只是 QA 的責任。
寶玉在《軟體工程之美》中強調:
很多團隊認為「測試保證品質」,這是錯誤的。測試只能發現問題,不能保證品質。品質來自每一個環節的認真對待。
品質的成本#
flowchart TD
subgraph P [💰 預防成本 - 最低]
P1[程式碼規範]
P2[設計評審]
P3[培訓]
P4[工具投入]
end
subgraph E [💵 評估成本]
E1[程式碼評審]
E2[測試執行]
E3[品質審計]
E4[監控告警]
end
subgraph I [💸 內部失敗成本]
I1[Bug 修復]
I2[返工重做]
I3[延期]
I4[團隊士氣]
end
subgraph O [💔 外部失敗成本 - 最高]
O1[客戶投訴]
O2[賠償損失]
O3[品牌受損]
O4[信任喪失]
end
P -->|投資不足| E
E -->|發現不及時| I
I -->|流入生產| O
style P fill:#c8e6c9
style E fill:#fff9c4
style I fill:#ffe0b2
style O fill:#ffcdd2在早期發現和修復問題的成本最低。投資於預防,而不是事後補救。
品質成本曲線與何時停止測試#
要把上面的成本概念用於決策,得先釐清一個常被混淆的事實:
測試本身不修復任何問題,它只蒐集資訊。 真正花錢的是「修 bug」與「bug 流入生產造成的損失」。因此「該測到什麼程度」本質上是一個資訊價值問題:再測一輪,能讓我多知道多少、避免多大的損失?
測試投入與發現的缺陷之間呈現邊際效益遞減:前期少量測試就能掃出大量明顯缺陷,越往後每多找到一個缺陷所需的成本越高。
flowchart LR
A[測試投入增加] --> B[初期: 大量缺陷被發現<br/>單位成本低]
B --> C[中期: 缺陷發現速度趨緩]
C --> D[後期: 投入大增<br/>僅找到罕見缺陷]
D --> E{再測的資訊價值<br/>是否高於成本?}
E -->|是| A
E -->|否| F[停止測試 / 轉移到下個風險點]何時停止測試? 不存在「測完」這回事,只有「值不值得再測」。可參考以下判準:
| 判準 | 說明 |
|---|---|
| 邊際資訊價值 | 再測一輪能降低的風險,已低於這輪測試的成本 |
| 缺陷發現曲線趨平 | 新缺陷發現率明顯下降,趨近水平 |
| 風險已落在閾值內 | 剩餘風險對業務可接受(高風險區域已優先測過) |
| 成本/時程約束 | 在既定資源下,把剩餘預算投到更高風險區域的回報更高 |
「追求 100% 覆蓋率」常落入後期的高成本低回報區。把最後那幾趴的力氣,轉投到尚未覆蓋的高風險路徑或預防活動上,整體 ROI 通常更高。
測試與程式碼品質#
品質保障建立在堅實的測試與程式碼審查實踐之上:
- 測試金字塔、覆蓋率、案例設計:詳見 測試基礎
- 自動化測試、CI/CD 整合、報告與度量:詳見 測試實踐
- Code Review 檢查清單與文化建立:詳見 Code Review
靜態分析#
常用的靜態分析工具:
- 語法檢查(ESLint、Pylint)
- 類型檢查(TypeScript、mypy)
- 安全掃描(SonarQube、Snyk)
- 複雜度分析
把靜態分析整合到 CI 流程中,問題程式碼不允許合入。這比事後發現問題成本低得多。
上線與發布#
發布策略#
寶玉介紹的發布方式:
滾動發布(Rolling Update):
- 逐步替換舊版本
- 過程中新舊版本共存
- 可以隨時回滾
藍綠部署(Blue-Green Deployment):
- 準備兩套環境
- 切換流量到新環境
- 問題時快速切回
金絲雀發布(Canary Release):
- 先給小部分使用者使用新版本
- 觀察指標正常後逐步擴大
- 發現問題只影響少量使用者
選擇建議:
├── 小更新:滾動發布
├── 大更新:金絲雀發布
├── 關鍵系統:藍綠部署
└── 多種組合使用灰度發布實踐#
灰度的維度:
- 按使用者 ID(內部使用者優先)
- 按地區(某個城市先上)
- 按比例(5% ➡️ 20% ➡️ 50% ➡️ 100%)
- 按設備(iOS 先上,Android 後上)
灰度過程中的監控:
- 錯誤率
- 響應時間
- 業務指標
- 使用者反饋
灰度不是萬能的。如果問題在灰度階段沒發現,全量後可能更難發現。灰度階段要認真監控。
安全實踐#
安全左移#
寶玉提出「安全左移」的概念:
安全問題越早發現成本越低。不要等到上線前才做安全測試。
各階段的安全實踐:
| 階段 | 安全活動 |
|---|---|
| 需求 | 安全需求分析、威脅建模 |
| 設計 | 安全設計評審 |
| 開發 | 安全編碼規範、程式碼審查 |
| 測試 | 安全測試、滲透測試 |
| 部署 | 配置審查、漏洞掃描 |
| 運維 | 監控、響應、更新 |
常見安全問題#
OWASP Top 10(簡化版):
注入攻擊:
├── SQL 注入
├── 命令注入
└── 防護:參數化查詢、輸入驗證
認證問題:
├── 弱密碼
├── Session 管理
└── 防護:多因素認證、安全會話
敏感資料:
├── 資料洩露
├── 傳輸不加密
└── 防護:加密存儲、HTTPS
訪問控制:
├── 越權訪問
├── 權限繞過
└── 防護:嚴格權限檢查永遠不要信任使用者輸入。所有外部輸入都要驗證和過濾。
生產事故處理#
事故響應流程#
喬新亮分享的事故處理原則:
flowchart TD
subgraph D [🔔 發現階段]
D1[監控告警] --> D2[快速確認問題]
D3[使用者反饋] --> D2
D4[內部發現] --> D2
end
subgraph R [⚡ 響應階段]
R1[組織響應團隊] --> R2[判斷影響範圍]
R2 --> R3[決定處理策略]
R3 --> R4[對外溝通]
end
subgraph H [🔧 處理階段]
H1[🚨 止血優先] --> H2[修復問題]
H2 --> H3[驗證恢復]
H1 -.- H1a["恢復服務最優先"]
end
subgraph P [📝 檢討階段]
P1[時間線梳理] --> P2[根因分析 5 Why]
P2 --> P3[改進措施]
P3 --> P4[經驗分享]
end
D --> R --> H --> P
style D fill:#ffebee
style R fill:#fff3e0
style H fill:#e8f5e9
style P fill:#e3f2fd事後檢討#
檢討的目的是學習和改進,不是追責。如果檢討變成追責會議,以後就沒人敢報告問題了。
好的檢討會議:
- 聚焦系統和流程,而非個人
- 鼓勵誠實說出問題
- 產出具體的改進措施
- 跟進改進的執行
無責事後檢討(Blameless Postmortem)#
「無責」不是「無責任」,而是把焦點從「誰犯了錯」轉移到「什麼樣的系統與流程讓這個錯誤得以發生而未被攔截」。它的前提是心理安全(psychological safety):團隊成員相信誠實揭露問題不會招致懲罰或羞辱。
無責文化是一種理性的工程選擇,而非「對人寬容」。一旦檢討變成問責會議,最直接的後果不是「大家更小心」,而是下次出事沒人敢第一時間上報——隱瞞會把一個小事故拖成業務災難。資訊的自由流動,遠比追究單一個人更有價值。
| 有責文化(要避免) | 無責文化(要建立) |
|---|---|
| 「是誰把它推上線的?」 | 「為什麼這個變更能在沒有把關下進到生產?」 |
| 結論是「某人要更小心」 | 結論是「補上自動檢查 / 防呆機制」 |
| 當事人防衛、避重就輕 | 當事人安心還原完整時間線 |
| 問題被掩蓋,下次重演 | 問題被攤開,系統被改善 |
設計檢討會議以維持心理安全:
- 開場明確聲明「目的是學習,不追責」,並由帶頭者以身作則
- 用被動、對事的語言(「變更未被攔截」而非「某某沒檢查」)
- 由當事人主述時間線——他最清楚現場,且這代表團隊信任他
- 把每條改進措施綁定到「系統/流程」而非「某人要更努力」
根因分析:5 Whys 的技巧與陷阱#
5 Whys 是最常用的根因分析法:對問題反覆追問「為什麼」,直到觸及可從制度上修復的根因。
事故:使用者下單後庫存超賣
├── 為什麼超賣? → 兩個請求同時扣到同一筆庫存
├── 為什麼會同時扣? → 扣庫存沒有加鎖/沒用原子操作
├── 為什麼沒加鎖? → 開發時不知道此路徑會被並發呼叫
├── 為什麼不知道並發? → 設計評審沒涵蓋並發場景
└── 為什麼評審沒涵蓋? → 缺少並發風險的評審檢查項 ← 可修復的根因修復點落在最後一層(補上評審檢查項 + 加上原子扣減),而不是停在「開發要更小心」。
5 Whys 的常見陷阱:
- 單線歸因:真實事故常是多因交織,硬要追成一條鏈會漏掉其他成因——必要時用魚骨圖(fishbone)或 5 Whys 多分支展開。
- 過早停在「人」:問到「某人疏忽了」就收手,等於把根因鎖定在個人,違背無責精神;應繼續追問「為什麼這個疏忽能造成事故」。
- 答案是猜的:每一層「為什麼」都應有證據(日誌、時間線)支撐,而非腦補。
- 追問次數教條化:「5」只是經驗值,達到可行動的系統性根因即可停,不必硬湊或硬砍。
檢討報告模板:
mindmap
root((檢討報告))
📋 事故概述
時間
影響範圍
持續時間
⏱️ 時間線
詳細的事件發展過程
🔍 根因分析
直接原因
根本原因(用 5 Why 分析)
📊 影響評估
業務影響
使用者影響
🛠️ 改進措施
短期修復
長期改進
責任人和時間表本章要點#
- 品質是團隊責任:不只是測試的責任
- 測試金字塔:大量單元測試,適量整合測試,少量 E2E
- Code Review:發現問題、共享知識、建立文化
- 灰度發布:逐步上線,邊發布邊監控
- 安全左移:越早發現安全問題成本越低
- 檢討不追責:目的是學習和改進