本章從建構(construction)的角度綜覽軟體品質技術。重點在於大局觀而非實作細節——協同開發、測試與除錯的實務建議請見後續三章。
20.1 軟體品質的特性#
軟體品質分為外部特性與內部特性兩大類。
外部特性(使用者可感知):
| 特性 | 說明 |
|---|---|
| 正確性(Correctness) | 系統符合規格、設計與實作的程度 |
| 可用性(Usability) | 使用者學習與操作的容易度 |
| 效率(Efficiency) | 對記憶體與執行時間等資源的最小化使用 |
| 可靠性(Reliability) | 在規定條件下執行功能的能力,即平均故障間隔時間 |
| 完整性(Integrity) | 防止未授權或不當存取的程度 |
| 適應性(Adaptability) | 不需修改就能用於其他環境的程度 |
| 準確性(Accuracy) | 輸出結果無誤差的程度(不同於正確性) |
| 強健性(Robustness) | 面對無效輸入或壓力環境仍能運作的程度 |
內部特性(開發者關注):
- 可維護性(Maintainability)、彈性(Flexibility)、可移植性(Portability)
- 可重用性(Reusability)、可讀性(Readability)
- 可測試性(Testability)、可理解性(Understandability)
mindmap
root((軟體品質))
外部特性
正確性
可用性
效率
可靠性
完整性
適應性
準確性
強健性
內部特性
可維護性
彈性
可移植性
可重用性
可讀性
可測試性
可理解性外部特性之間常互相衝突——例如追求正確性會傷害強健性,但適應性卻有助於強健性。在特定專案中應明確決定哪些品質目標優先,並意識到它們之間的取捨關係。
內部特性最終會影響外部特性:不可維護的程式碼會削弱正確性與可靠性,缺乏彈性則影響可用性。
20.2 改善軟體品質的技術#
軟體品質保證(Software Quality Assurance)是一套系統性的活動計畫,涵蓋以下面向:
品質相關活動#
| 活動 | 說明 |
|---|---|
| 明確的品質目標 | 沒有明確目標,程式設計師會各自優化不同面向 |
| 顯性的品質保證活動 | 組織必須讓品質成為可見的優先項目,而非獎勵「快而髒」的開發方式 |
| 測試策略 | 執行測試能評估可靠性,但不能獨力承擔品質保證的重擔 |
| 軟體工程準則 | 適用於問題定義、需求、架構、建構與系統測試各階段 |
| 非正式技術審查 | 桌面檢查(desk-checking)或與同儕走查程式碼 |
| 正式技術審查 | 利用「品質閘門」(quality gate)在各階段轉換時進行檢視或審計 |
| 外部稽核 | 由外部團隊評估專案狀態或產品品質 |
開發流程面#
- 變更控制程序——不受控的變更是品質的大敵,會導致需求、設計與程式碼之間的不一致
- 成果量測——不量測就無法得知品質計畫是否有效
- 原型開發(Prototyping)——研究顯示原型有助於改善設計、滿足使用者需求與提升可維護性
設定目標的力量#
Weinberg 與 Schulman(1974)的實驗:五個團隊各自被指定優化不同目標(最小記憶體、最清晰輸出、最可讀程式碼、最少陳述式、最短開發時間)。結果五組中有四組在被指定的目標上排名第一,另一組排名第二——但沒有任何一組在所有目標上都表現良好。啟示:程式設計師確實會朝你設定的目標努力,但目標之間會互相衝突,不可能全部同時達到最佳。
20.3 不同品質保障技術的相對效能#
缺陷偵測率#
各技術的缺陷偵測率(modal rate)差異顯著:
| 技術 | 最低 | 典型 | 最高 |
|---|---|---|---|
| 非正式設計審查 | 25% | 35% | 40% |
| 正式設計檢視 | 45% | 55% | 65% |
| 正式程式碼檢視 | 45% | 60% | 70% |
| 建模/原型 | 35% | 65% | 80% |
| 個人桌面檢查 | 20% | 40% | 60% |
| 單元測試 | 15% | 30% | 50% |
| 整合測試 | 25% | 35% | 40% |
| 系統測試 | 25% | 40% | 55% |
| 高流量 Beta 測試(>1000 站點) | 60% | 75% | 85% |
沒有任何單一技術的典型偵測率超過 75%,平均約 40%。最常見的單元測試+整合測試組合典型偵測率僅 30-35%。典型組織以測試為主的方式只能達到約 85% 的缺陷移除效率;領先組織使用多種技術可達 95% 以上。
組合的力量#
Myers(1978)的研究發現:任何兩種方法的組合——即使是兩組獨立的人使用相同方法——都能將發現的缺陷數量增加近一倍。原因是不同人與不同方法傾向發現不同類型的缺陷:檢視中僅約 20% 的錯誤被多於一位檢查者發現。
Extreme Programming 的預估缺陷偵測率
XP 的實踐組合(配對程式設計作為非正式審查+桌面檢查+單元測試+整合測試+回歸測試)預估可達到:
- 最低 ~74%、典型 ~90%、最佳 ~97%
這遠優於業界平均的 85%,但並非 XP 獨有的「協同效應」——任何類似的多技術組合都能達到相當效果。
缺陷發現與修正的成本#
- 檢視(inspection)比測試更經濟:程式碼閱讀每小時偵測到的缺陷比測試多 80%(SEL 研究)
- IBM 研究:程式碼檢視每個錯誤需 3.5 人時,測試則需 15-25 人時
- Microsoft 應用部門:檢視找到並修復一個缺陷需 3 小時,測試需 12 小時
- 檢視是「一步到位」技術(同時發現症狀與根因),測試是「兩步」技術(先發現症狀,再診斷根因),因此成本差異顯著
建議的高品質組合策略:(1) 對所有需求與架構進行正式檢視,關鍵設計亦然;(2) 建模或原型開發;(3) 程式碼閱讀或檢視;(4) 執行測試。
20.4 什麼時候進行品質保證工作#
錯誤越早植入系統,就越與其他部分糾纏,修正成本越高。一個需求錯誤可能在設計中產生多個對應錯誤,進而在程式碼中產生更多錯誤——額外的架構、程式碼、測試案例與文件都可能需要丟棄。
單一架構錯誤可能影響數個類別與數十個常式,但單一建構錯誤通常只影響一個常式或類別。
品質保證應貫穿整個專案:在工作開始時規劃、在進行中成為技術基礎、在結束時驗證產品品質。不應只集中在最後階段。
20.5 軟體品質的一般原則#
軟體品質的一般原則:提升品質會降低開發成本。
關鍵觀察:提升生產力與品質的最佳方式是減少花在重工(rework)上的時間。業界平均每人每天僅產出 10-50 行交付程式碼,而最大的時間消耗是除錯與修正——在傳統開發週期中佔約 50% 的時間。
實證支持:
- NASA SEL 研究(50 個專案、400+ 人年、近 300 萬行程式碼):增加品質保證活動降低了錯誤率,但未增加整體開發成本
- IBM 研究:缺陷最少的專案擁有最短的開發時程與最高的生產力
- DeMarco 與 Lister(1985):166 位程式設計師中,花費中位數時間完成的人缺陷最多;花更多或更少時間的人缺陷反而顯著更少
品質最終是免費的——它將資源從下游的除錯與重工,重新分配到上游的品質保證活動。上游活動對產品品質的槓桿效應更大,因此上游投入的時間能在下游節省更多時間。
更多資源#
- Ginac, Customer Oriented Software Quality Assurance (1998)——品質屬性、品質指標與 QA 計畫
- Lewis, Software Testing and Continuous Quality Improvement, 2nd ed. (2000)——品質生命週期與測試技術
- 相關標準:IEEE Std 730(品質保證計畫)、IEEE Std 1061(品質指標方法論)、IEEE Std 1028(軟體審查)
要點#
- 品質最終是免費的,但需要將資源從昂貴的修復重新分配到廉價的預防
- 品質目標之間會互相衝突,應明確決定優先順序並傳達給團隊
- 沒有任何單一缺陷偵測技術能獨當一面;成功的品質計畫需結合多種技術來捕捉不同類型的錯誤
- 建構階段有有效技術可用,建構前同樣有強大的技術;越早發現缺陷,修正成本越低
- 軟體品質保證是流程導向的——軟體開發不像製造業有重複階段,品質由開發流程決定