「測試可以令人信服地證明 bug 的存在,卻永遠無法證明它們不存在。」——電腦科學先驅戴克斯特拉(Edsger W. Dijkstra)

「測試所有東西」是不可能的要求#

作者曾被一位測試經理請去諮詢,因為他的上司要求他「測試所有東西」。這是個不可能達成的要求,原因有三:

  • 人腦不只會犯錯,容量還是有限的
  • 沒有人能永遠活著——就算我們想得到所有可能的測試,也活不到把它們全做完
  • 對多數情境而言,這樣做的成本太高,因為任何程式的可能測試數量是無限的

可能的測試數量是無限的#

設想一個最簡單的程式:每按一次空白鍵就在螢幕顯示「Hello Dolly!」,按其他任何鍵都不該有反應。如果你看不到程式內部,需要執行多少測試案例才敢拿性命打賭「所有可能性都測過了」?

答案是無限多——或至少「多到我一輩子也跑不完」。

由於看不到內部,你無從得知設計者埋了什麼怪異條件。例如程式可能設計成:先按 W、空白鍵三次、M、空白鍵三次、J,再敲恰好 168 個不含字母 L 的鍵,螢幕才會跳出「Whaaa?」——你那套「窮舉」測試會抓到這種離譜的隱藏行為嗎?

這並非天方夜譚。作者曾在一次技術審查(technical review)中,發現一位程式設計師在號稱高度安全的應用中植入了後門(backdoor):她改寫密碼保護機制,讓自己無論真實密碼設成什麼都能隨時侵入。一套在嚴格控管下執行的精密測試計畫都沒能找到它,這個後門藏了三年,直到技術審查才現形。

組態、順序、記憶與隨機性#

就算只看單一程式,要「完整」測試也幾乎不可能,因為變數會層層相乘:

  • 組態(configuration):若程式須在 10 種 CPU × 10 種記憶體 × 10 種磁碟上運作,就有 1000 種組態。再加上不同廠牌、驅動程式、作業系統版本、同時執行的其他程式與周邊裝置,組合會暴增到數千兆種
  • 順序效應:10 個功能不只要做 10 個測試,因為不同執行順序可能產生不同結果——要涵蓋所有順序需 10 階乘(10!,超過六百萬)個測試
  • 記憶:所有真實程式都有記憶,第二次跑同一序列未必得到和第一次相同的結果
  • 真正的隨機性:例如外部裝置觸發中斷的確切奈秒、你敲下某鍵的確切微秒

一句話總結:測試可以累死人(exhausting),卻永遠無法窮盡(exhaustive)。

測試充其量是「抽樣」#

既然無法測試所有東西,任何一組真實的測試都是某種抽樣(sampling)——從所有可能測試中取出一部分作為代表。我們當然希望它具代表性,但「對誰而言具代表性?」抽樣本質上又是一個心理且情緒性的過程:滿足某人的樣本,可能完全無法滿足另一人。

作者以「雨量計」為例:他家門廊上開口很小的雨量計,適合西雅圖那種綿密細雨,卻完全測不到佩科斯峽谷(Pecos Canyon)那種大顆、稀疏、間隔數英寸落下的雨滴——暴雨過後計量底部竟是乾的。同事打趣說:「你(被淋濕的鬍子)比門廊上的雨量計更準。」

反過來,若剛好有一兩滴大雨落進小開口,計量又會誇大雨量。測試也常如此:取一個小樣本,最後對整個產品的問題密度做出低報或高報

資訊的成本可能超過無知的成本#

無法窮舉測試,把我們夾在兩個既困難又同時必要的目標之間:

  1. 我們想涵蓋所有有意思的條件
  2. 我們想把測試集縮減到可管理、負擔得起的程度

關於第一點:測試人員常在「沒在找某類 bug」時意外撞見關鍵 bug,像早餐麥片裡突然出現一隻螞蟻。這究竟是純運氣,還是有方法能找到更多這類「驚喜 bug」?作者認為部分答案在於擴大我們對「測試」的想像

也許能用更少的測試取得更多資訊#

如今許多人關注的是第二個目標——縮減測試集。曾有測試人員求助:「我們從三十人的團隊裁到三人,卻還要『確保』產品品質,我該怎麼決定要測什麼?」

顧問的回答很關鍵:「首先,認清任何一組測試都是一種抽樣策略;接著,無論資源多寡,都盡你所能挑出最具代表性的那一組測試。」

作者用「測試自助餐(Testing Buffet)」比喻這個處境:你只拿一個盤子,面對擺滿用例、邊界條件、相容性測試、互動測試、權限矩陣的長桌,且只能走幾趟。不同個性的人面對限制反應各異:

  • 有人不停向領班抱怨盤子太小,掃了大家的興
  • 有人氣呼呼地轉身走人,因為他認為不該被限制食量
  • 有人從頭開始,只裝最先吸引他的前兩道菜

當面對「無法克服的測試任務」(測試的常態),你可能想「從頭做起、看時間內能進展多少」,或「在所有功能間挑簡單快速的測試」。這兩種都對測試人員很方便,但能否構成一頓「營養均衡的測試」?

要測得好,測試人員必須意識到有限測試、資源與時間的限制,也必須意識到自己的個性——自己慣於用哪種方式「攻略自助餐」。管理者同樣須認清這些限制:無論多想要,你都不能期待測試人員做「窮舉」測試。

小結#

任何待測產品的可能測試數量本質上是無限的。與其要求做「所有」測試,管理者與測試人員都必須努力理解抽樣為測試流程帶來的風險

常見錯誤#

以下是面對「無法窮舉」這個現實時最常見的失誤。

  1. 要求「測試所有東西」:當你要求不可能的事,你不知道會得到什麼,只知道不會是「不可能的事」
  2. 不理解抽樣:極少數人真正懂抽樣,請自我教育或聘請專家稽核你的抽樣,並隨時準備面對抽樣誤差
  3. 為不值得的資訊花太多錢:想想那些買來卻從沒真正想要的昂貴器材——那些錢和空間本可用在別處
  4. 為了表面功夫而測試:有些客戶或認證機構要求「測試」,你可以照做,但至少別欺騙自己關於資訊品質的真相
  5. 沒用上所有資訊來源:測試結果的資訊本質上有限,但若你夠警覺,身邊還有其他種類的資訊
  6. 以為機器能做人做不到的窮舉測試:受限的不只是人腦,測試工具也有極限。別買宣稱能「執行所有測試」的產品——就算它做得到,你也不可能看完所有結果
  7. 以限縮資源來增加風險:測試資源被砍時,最容易的反應是縮小樣本(少跑測試),但這會讓抽樣誤差更可能發生。多元的樣本可能比龐大的樣本找到更多問題;同理,讓測試團隊更多元,可能比單純擴編更有效