🎯 什麼情境該想到我
當你以為「測完就沒事了」的時候。 這本書用一整排實證數據說明:測試單獨使用的檢錯能力遠比想像中低,而正式的**檢查(inspection)**才是抓錯主力。
單一的軟體測試方法只能取得有限的效果——單元測試的檢錯比僅為 25%,功能測試為 35%,而集成測試為 45%,相比之下,設計和程式碼檢查的檢錯比平均為 55%、60%。(p.384)
錯誤發現百分比(表 23-1,摘自 Jones 1986,p.379)
| 步驟 | 最低比 | 中等比 | 最高比 |
|---|---|---|---|
| 對設計文件的人工檢查 | 15% | 35% | 70% |
| 非正式組內設計檢查 | 30% | 40% | 60% |
| 正式設計檢查 | 35% | 55% | 75% |
| 正式程式碼檢查 | 30% | 60% | 70% |
| 模型或原型 | 35% | 65% | 80% |
| 人工程式碼檢查 | 20% | 40% | 60% |
| 單元測試(單個子程式) | 10% | 25% | 50% |
| 功能測試(相關於程式) | 20% | 35% | 55% |
| 系統測試(整個系統) | 25% | 45% | 60% |
| 段測試(動態資料) | 35% | 50% | 65% |
| 集成測試(綜合使用) | 93% | 99% | 99% |
書中對此表的兩點結論(p.379–380):
- 任何單一方法的中等比都不超過 65%——單靠一招是不夠的。
- 要拿到高檢錯比就必須綜合幾種方法。Jones 指出單元測試、功能測試、系統測試綜合應用的集成檢錯率不會低於 60%,這對商業軟體是合適的(p.380)。
實際案例的數字(p.385,除註明外)
| 案例 | 數字 | 頁碼 |
|---|---|---|
| 某次軟體維護:引入程式碼檢查前,聯機(線上)維護修改是錯誤的比例 | 55% | p.385 |
| 同上,引入程式碼檢查後 | 2% | p.385 |
| 應用程式碼檢查法一次就可改正的錯誤比例 | 95% | p.385 |
| 未用程式碼檢查法,一次能糾正的錯誤比例 | 20% 以下 | p.385 |
| 同一開發組 11 個程式:未用評審的 5 個,每百行程式碼錯誤數 | 4.5 個 | p.385 |
| 同上,經過評審的 6 個,每百行程式碼錯誤數 | 0.82 個(減少 80% 以上) | p.385 |
| Aetna 保險公司:可通過檢查發現的錯誤比例 | 82% | p.385 |
| Aetna 保險公司:檢查可將開發資源減少 | 25% | p.385 |
| IBM 500,000 行 Orbit 專案(用了 11 種檢查方法):所產生的錯誤僅為正常情況的 | 1% | p.385 |
| AT&T 一個超過 200 人的機構:採用評審檢查後生產率提高 | 14% | p.385 |
| 同上,錯誤減少 | 90% | p.385 |
| 噴射推進實驗室估計:早期發現和定位錯誤,每次檢查可節省 | 25,000 美元 | p.385 |
| 設計與程式碼檢查聯合使用可去除產品中的錯誤 | 60% 到 90% | p.386 |
| 檢查可提高生產率約 | 20% | p.386 |
| 使用設計和編碼檢查的專案,檢查佔專案總時間 | 15% | p.386 |
檢查 vs. 除錯的成本(第 23 章)
| 比較 | 數字 | 頁碼 |
|---|---|---|
| 微軟應用部:程式碼檢查一步法發現並改正一個錯誤 | 3 小時內 | p.380 |
| 微軟應用部:除錯二步法發現並改正一個錯誤 | 12 小時內 | p.380 |
| Collofello 與 Woodfied,700,000 行、逾 400 人的專案:程式碼檢查與除錯的收效比 | 1.38 : 0.17 | p.380 |
| NASA 軟體工程實驗室:閱讀程式碼比除錯每小時多發現的錯誤 | 80% 多 | p.380 |
| NASA 軟體工程實驗室:程式碼閱讀每小時發現錯誤數 vs. 除錯(Card 1987) | 3.3 個 vs. 1.8 個 | p.391 |
| NASA 軟體工程實驗室:只有兩位程式碼閱讀者,通過程式碼閱讀發現的錯誤 | 29% | p.379 |
書的關鍵論證(p.380):有些方法(如人工檢查)一步就完成「發現+改正」,測試則是「發現」之後還要另外分析與改正的二步方法。一步法比二步法更划算。
⚙️ 怎麼用
書把「評審」當成總稱(檢查、普查、程式碼閱讀等別人查看你工作的方法,p.384),其中檢查(inspection)是最有實證支持的那一種(Michael Fagan 發明,在 IBM 用了幾年後由 Fagan 出版發行,p.386)。以下是書中檢查的可執行流程。
一、先確認你做的是「檢查」而不是隨便看看(p.386)
檢查與走馬看花式的參觀不同,必須具備:
- 用檢查表把檢查員的注意力集中在過去所遇到的問題領域
- 側重於錯誤檢查而不是糾錯
- 評審者在檢查之前先舉行預備會議,最後得出的問題經過共同討論
- 所有參加者被分配不同的任務
- 檢查協調者不是被檢查產品一方的人
- 協調者在協調檢查方面受過訓練
- 每次檢查的數據都被收集,回饋給今後的檢查
- 一般管理人員不參加檢查會議(技術主管則可能參加)
二、分派角色(p.386–387)
| 角色 | 職責 |
|---|---|
| 協調者 | 控制檢查進度(既有速度又能最大限度發現錯誤);分配受檢的設計/程式碼/檢查表、確立會議室、報告檢查結果、落實會議所確定的內容。須有技術能力但不必是該設計或程式碼的專家。 |
| 專案主持者(設計者/程式碼撰寫人) | 在檢查中扮演相對次要的角色。若設計或程式碼不清晰,主持者被告知修改使其更清楚;否則要解釋不清晰處,甚至解釋為何看起來有錯的部分實際可接受。若檢查者不熟悉專案,由他做簡介。 |
| 檢查者 | 任何對設計或程式碼有直接興趣、但不是本專案主持者的人(可包含測試者或高水平的結構人員)。任務是發現缺陷。 |
| 記錄員 | 記錄所發現的錯誤與會議情況。可由協調者或另外的人兼任,但主持者與檢查者不得兼任。 |
| 管理者 | 有權知道檢查結果,檢查報告應讓管理者知道;但不參加檢查會議——管理者出現會把重心從技術轉移到政治上。 |
規模(p.387):
- 一次檢查至少三個參加者:協調者、主持者、檢查者,且三個角色不能各自兼任。
- 一般把檢查組控制在 6 人左右,再多就難以管理。
- 噴射推進實驗室的研究:三人以上的檢查組並不能提高所發現的錯誤總數。
三、跑七個階段(p.387–388)
- 計劃——主持者把設計或程式碼交給協調者;協調者決定誰參與、何時何地開會,並把設計、程式碼與檢查表分發給每位檢查員。
- 總覽(僅在檢查員不熟悉專案時)——主持者花一小時左右介紹產生設計或程式碼的環境。書明講這件事不容易,因為它容易給需檢查的東西造成不清晰的假象;設計或程式碼應能自己站得住腳,總覽不應提及它。
- 準備——每位檢查者花 90 分鐘熟悉設計或程式碼,使用檢查表指導檢查工作。
- 高階語言的應用程式程式碼:每小時可先閱讀 700 行
- 高階語言的系統程式程式碼:每小時只能閱讀 125 行
- 最有效的速度差異很大,要記錄自己團隊的速度。
- 檢查會議——協調者請人(通常是主持者)解釋設計或程式碼的閱讀,所有邏輯都要解釋,包括每個邏輯結構的分支。發現錯誤就記錄下來並標明重要性,確認是錯誤後就停止討論,繼續往下走。
- 最佳檢查速度:系統碼每小時 90 行;應用程式碼每小時可提高到 500 行。太慢注意力會鬆懈且效率低,太快會漏掉應發現的錯誤。
- 會議中不必討論解答,應著重於確定錯誤。有些檢查組甚至不允許爭論「這算不算真錯誤」——因為如果錯誤的是非會被弄混淆,相應的設計、程式碼與文件本來就需要澄清。
- 會議不超過兩小時。IBM 與其它公司的經驗:檢查者無法一次全神貫注超過 2 小時。同一天安排多次檢查也不明智。
- 檢查報告——會議後協調者編制報告,列出每個錯誤的類型與嚴重性。若能持續收集「所花時間」與「所發現錯誤數」,就能用硬數據判定檢查員的工作效率。
- 再工作——協調者把錯誤交給某人(通常是主持者)逐一改正。
- 執行——協調者負責檢查再工作的執行。若超過 5% 的設計或程式碼需再加工,整個檢查過程應重新進行;低於 5% 則協調者可要求再檢查或親自證實。
⚠️ 書的硬性要求:檢查過程的所有部分都是必需的。「已經發現,去掉或合併其中任意幾個部分都將耗去更多的代碼。如果你想改變檢查過程而沒有一種可以度量改變的方法,那麼你就別這樣做。」(p.388)
四、養一份自己的檢查表(p.388)
- 觀察哪些類型的錯誤較常發生,建一份表把注意力引到那裡。
- 時間久了,發現新錯誤就加進去,不再出現的錯誤就從表中拿掉。
- 把檢查表限制在一頁之內——太長的檢查表在所要求的細節水平上很難使用。
書中「有效檢查法」自檢清單(p.389):檢查表是否引向過去常發生錯誤的地方?是否側重缺陷檢查而非糾錯?會前每位檢查員都準備夠了嗎?每位參與者是否扮演不同角色?會議是否限制在 2 小時內?協調者是否受過特殊訓練?是否收集了錯誤類型數據與準備/檢查率?指定的條款是否都落實?管理員是否明白為什麼他不參加?
五、選不了檢查時的替代方案(24.3 節,p.389–391)
| 方法 | 書怎麼說 | 頁碼 |
|---|---|---|
| 普查(walkthrough) | 定義寬鬆,兩人以上討論設計或程式碼即可;通常花 30–60 分鐘;由主持者採用;侧重發現錯誤而非糾正;管理人員不參加。能發現 30%–70% 的錯誤(Myers 1979、Boehm 1987、Yourdon 1989)。 | p.389–390 |
| 程式碼閱讀 | 開會前把 1000–10000 行(典型 4000 行)源碼分發出去;至少 2 人各自閱讀(速度約每天 1000 行);讀完由開發者主持 1–2 小時討論會,會議不是必需的。特點是側重個人閱讀而非會議討論,評審員不在一起時相當有價值。 | p.391 |
| 軟體演示 | 向用戶展示軟體品質良好,屬於管理評審而非技術評審。 | p.391 |
檢查 vs. 普查的差別(p.390)——檢查全是「是」,普查全是「否」:正規協調者培訓、參與者分工明確、有檢查表告訴你「怎樣發現錯誤」、集中評審量尋找最常見類型的錯誤、正規執行以減少不正確的定位、對結果的分析導致效率提高、對「導致發現錯誤的數據」的分析反過來也提高效率。此外普查由作者主持(檢查由協調者主持),且普查因回饋較弱,對減少後期錯誤「影響不大」。
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
- 檢查不是為了評估人。 「檢查結果不應該用來作為對性能的評估。不要殺死正在下金蛋的天鵝。」性能評估應建立在最終產品之上,而不是未完成的工作之下(p.387)。
- 不准人身攻擊。 檢查組不能對主持者說「有一些人是笨蛋應讓其捲鋪蓋滾蛋」;像「任何知道 Pascal 語言的人都知道從 Num 迴圈到 0 是更為有效」這類評論根本不合適,協調者應把這點明白無誤地表達出來(p.388)。
- 主持者對錯誤有最終處置權。 主持者應接受每個被指出的錯誤並繼續下去——接受評論不代表認同它正確;檢查之後主持者可獨立考慮每個問題並決定是否有效。檢查者應尊重這個權力(p.388)。
- 評審不能取代測試,是互補。 「評審往往比測試要能發現更多種不同的錯誤,意味著你應使用評審或除錯方法以確保軟體品質」(p.392);且「即使除錯相當有效,評審對一個程式的集成性質量保證是必需的」(p.385)。
- 普查用不好會虧錢。 普查的最低效率為 30%,「這並無多大價值」。至少一個組織(Boeing Computer Services)發現對程式碼的掃視檢查「異常不合算」;Boeing 還發現說服人員自始至終應用普查很困難,壓力增大時幾乎不可能(Glass 1982,p.390)。
- 成本評估的前提要注意。 1978 年 Myers 研究之前,人工檢查的代價是測試的兩倍——但書指出該研究對象缺乏檢查經驗;人有了經驗後檢查才更有效。用某系統三次交付(發現率 15% → 41% → 61%)修正後,可得出「對每個錯誤來說檢查的代價僅為除錯的一半而不是兩倍」的結論(p.380)。
- 某些專案品質保證確實更貴。 「如果你在為航天飛機或生命保障系統編寫程式碼,可靠性需求會使本專案花費更多」(p.382)。
- 關於表格數字的一點小心。 第 24 章行文說「集成測試為 45%」(p.384),而第 23 章表 23-1(p.379)中 45% 對應的是「系統測試(整個系統)」的中等比,表中「集成測試」那列是 93/99/99(綜合使用多種方法)。引用時請照原頁碼標註,不要混用。
🔗 相關工具
- 工具-建構的先決條件(同書)——錯誤越早抓越便宜。本卡是同一原則的下游證據:「錯誤進入軟體的時間越早,它就越深藏於軟體的其它部分中,也就越不易將其移去」(p.381);「你發現錯誤越早,其所引起的損失也越小」(p.383)。
- 工具-管理複雜度(同書)——檢查會議要求「所有的邏輯都要解釋,包括每個邏輯結構的分支」(p.387);解釋不清的程式碼本身就是被檢查出來的缺陷。
- 工具-系統化除錯(程式設計實務)——分工不同:檢查是預防(在錯誤進入產品前攔截),除錯是事後(錯誤已經發生後追查)。書把兩者當成互補而非替代:人工檢查與電腦除錯各自擅長不同類型的錯誤,「成對地使用錯誤檢查方法要比單獨使用好」(p.380)。
- 回連 程式碼大全(第 23 章「軟體品質概述」+第 24 章「評審」,p.375–393)