你是否曾經遇過這種情況:測試案例全部跑過了,自動化測試全是綠燈,你信心滿滿地簽核了發佈。結果上線不到一小時,客服電話被打爆,老闆衝進來問:「為什麼這個 Bug 沒測出來?」
你很委屈。你明明測了啊!規格書上寫的你都驗證了。
問題出在哪?問題在於我們往往把「測試」當成了「驗證」(Verification),也就是確認「軟體是否符合預期」。但真正的測試,其實是一種批判性思考的過程。

測試大師 Michael Bolton 給了我們一個當頭棒喝的定義:
「測試是對軟體進行批判性思考的展現,目的是為了幫助人們做出更好的決定。」
我們的目標不是證明軟體「沒問題」,而是要在所有人都覺得「穩了」的時候,保持一種「專業的不確定性」(Professional Uncertainty)。
接下來將帶你拆解大腦的運作機制,教你如何識別那些偽裝成事實的「假設」,並提供一些提問技巧,讓你從「按表操課的測試員」進化為「擁有透視眼的偵探」。
你的大腦有兩個系統,而它們都想騙你
要了解為什麼我們會漏測 Bug,首先得了解我們的大腦是怎麼運作的。諾貝爾獎得主 Daniel Kahneman 在《快思慢想》中提出了兩個系統的概念,這在測試中至關重要。
系統一(System 1):直覺反應
admin/123456。當你看到綠色的按鈕,你直覺認為它是「確定」。系統二(System 2):反思
我們的目標是刻意喚醒系統二,因為測試需要批判性思考。
批判性思考不是要你拋棄直覺(系統一),而是要你在享受直覺帶來的速度時,設下幾個「減速帶」,強迫大腦切換到系統二進行檢查。
推論 vs. 假設:測試人員的致命陷阱
測試人員最常犯的邏輯錯誤,就是把「假設」當成了「事實」。讓我們來搞懂這兩者的差別
推論(Inference):我看到證據 A,所以我認為 B 是真的。
例如Log 顯示 "Database Connection Timeout",所以我推論資料庫連線有問題。這是合理的。
假設(Assumption):我沒有足夠的證據,但我依然認為 B 是真的。
例如:開發人員跟我說:「我只改了一行程式碼,不會影響其他功能的。」於是我假設真的沒影響,就沒測回歸測試。這就是災難的開始。
我們不可能在完全沒有假設的情況下生活(比如你現在假設你的椅子不會突然崩塌),但你需要管理它們:
魯莽的假設:絕對不要做。
例子:「那個 API 是 Google 提供的,Google 不會出錯,所以不用測 Exception handling。」(Google 當然會掛點!)
有風險的假設:可以做,但要大聲說出來。
例子:「因為時間不夠,我假設這次更新不會影響到舊的 iOS 版本,所以我只測了 iOS 16。」你必須把這個假設寫在測試報告裡。
Michael Bolton 列出了十個警訊,當你的想法符合以下特徵時,你的警報器要響起來:
這時候我們來看一個案例:計算機測試
如果你把一台計算機摔在地上,然後問:「我該怎麼測試它壞了沒?」
大多數人會說:「按按看 1+1=2。」
批判性思考者會先問:「我撿起來的時候,電池還在裡面嗎?螢幕有裂痕嗎?搖晃時有零件聲嗎?」不要直接跳進「測試執行」,先檢查你的「前提假設」。
不要當感恩節的火雞(歸納法的陷阱)
這是一個來自 Nassim Taleb 的經典故事,用來解釋為什麼「過去的經驗不能預測未來」。
想像有一隻世界上最聰明的火雞。
第 1 天:農夫來餵我吃玉米。生活真美好。
第 100 天:農夫還是餵我吃玉米。農夫愛我。
第 1000 天:根據過去 1000 天的數據分析,信賴區間 99.9%,明天農夫一定會餵我吃玉米。
第 1001 天:感恩節前夕。農夫拿著刀進來了。
這給測試人員什麼教訓?
「通過」的測試無法證明沒有 Bug,它只能證明「目前為止還沒發現 Bug」。
批判性距離:為什麼開發者測不出自己的 Bug?
這不是因為開發者技術不好,而是因為他們的「批判性距離」(Critical Distance)太近了。讓我們來看看兩種不同的心態:
建構心態(Building Mindset):
開發者的工作是「無中生有」。他們專注於「如何讓它跑起來」、「設想成功的路徑」。這是一種聚焦(Focusing)的思維。
測試心態(Testing Mindset):
測試者的工作是「審視」。我們專注於「它哪裡會壞掉」、「預期失敗」。這是一種去焦(Defocusing)的思維,看整體、看邊緣、看沒人注意的角落。
要一個人瞬間從「我要讓它成功」切換到「我要證明它會失敗」,是非常困難的。這就是為什麼我們需要獨立的測試角色,或者至少要進行角色扮演(Role Play)。
那我們要如何拉開距離?可以試試以下方式:
測試人員的四把思維手術刀: Huh? Really? And? So?
當你的直覺告訴你「這沒問題」時,Michael Bolton 建議用這四個詞來強制啟動你的「系統二」思考。
第一把刀:Huh?(蛤?):困惑是發現的開始
當你看到一個奇怪的現象,別急著解釋它(例如「喔那應該是網路卡頓」)。
停下來,發出「蛤?」的聲音。
第二把刀:Really?(真的嗎?):挑戰證據
這是在檢驗「事實」的含金量。你可以從以下面向來做檢查:
數據檢驗:「你說這功能修好了。Really? 你看到什麼?你測了什麼場景?Log 在哪裡?」
相對性原則(The Relative Rule):「這個系統很好用。」
Really?對誰來說好用?對工程師?還是對第一次使用的阿嬤?
Really? 什麼時候好用?在辦公室 Wi-Fi 下?還是在高鐵過山洞的 4G 訊號下?
來源檢驗(Says Who?):「文件上說這個欄位必填。」
Really?這是誰寫的?是什麼時候寫的?現在還適用嗎?
第三把刀:And?(還有嗎?):打破單一解釋
這是我最喜歡的一招。人類喜歡簡單的因果關係,但軟體是複雜的。
「如果你對一個現象想不出至少三個合理的解釋,代表你想得還不夠多」。
Weinberg 認為,當我們只有一個想法時,我們處於「執迷」狀態;當有兩個想法時,我們處於「兩難」困境;唯有當我們擁有三個或以上的想法時,我們才真正開始具備「選擇」與「深度思考」的能力。以下我們看看幾個範例:
範例一:軟體測試中的 Bug 成因分析
假設你在測試中發現系統在高負載下會崩潰。
想法 1(直覺): 可能是記憶體洩漏(Memory Leak)。
想法 2(對立): 可能是資料庫連線池(Connection Pool)不夠。
想法 3(Rule of Three): 可能是第三方 API 的回應逾時導致執行緒阻塞,或者是測試環境的網路頻寬被限制。
透過強迫思考第三種可能性,你避免了在記憶體和資料庫之間瞎猜,進而發現了隱藏的外部依賴問題。
範例二:需求分析與共識
客戶提出:「系統必須支援一鍵匯出所有報表。」
解釋 1: 客戶想要一個簡單的操作介面。
解釋 2: 客戶可能擔心手動操作太慢。
解釋 3(Rule of Three): 客戶可能需要將資料定期備份到另一個系統,或者他們其實是在處理某種合規性審查,需要整批資料。
當你思考第三種解釋時,你會發現「一鍵匯出」可能不是最佳解,自動化的 API 對接或是排程備份或許更能解決客戶的根本痛點。
A vs. The
永遠不要說「找到了 The problem(那個問題)」,要說「找到A problem(一個問題)」。因為問題通常是一整串的蟑螂,你看到一隻,通常還有十隻。
倖存者偏差(What's missing?):
二戰飛機的經典案例:美軍統計飛回來的飛機,彈孔多分布在機翼,所以決定加強機翼裝甲。統計學家說「錯!應該加強沒有彈孔的地方(引擎、駕駛艙)」。因為被打中那些地方的飛機根本飛不回來讓你統計。
在測試中要如何應用這個觀念呢?不要只看你「測過的案例」,要問「我們沒測什麼?」。不要只看「回報的 Bug」,要問「那些被取消的專案、那些沉默的用戶沒說出的問題是什麼?」。
第四把刀:So?(所以呢?):連結價值與風險
這是在問影響力。當你發現一個 Bug,開發者說「這還好吧」,你就用So? 攻擊。
不要只說「系統拋出 500 Error」。要說一個故事來說明這個Bug所帶來的風險:
受害者(Victim):誰倒楣?(正在搶演唱會門票的粉絲)
問題(Problem):發生什麼事?(付款了但沒拿到票)
威脅(Threat):什麼觸發的?(瞬間高流量)
漏洞(Vulnerability):為什麼?(資料庫鎖死機制設計不良)
大腦裡的 Bug:常見的認知偏誤
我們在找程式的 Bug,但誰來找我們腦袋裡的 Bug?以下是測試人員最容易中的招:
範例 1:「這個軟體很有品質。」品質不是一個「東西」,品質是一種關係(這軟體對某個人有價值)。
範例 1:「我有 500 個 Test Cases。」但是事實上,測試是一種活動,不是文件。不要以為寫好文件就等於測試完了。
二元思考(Binary Thinking):
我們可能會認為 要就是測試通過,要不然就是測試失敗。但是世界不是非黑即白的。測試通過可能只是因為輸入的數據太簡單。軟體可能「功能正常」但在「使用者體驗」上爛透了。
自動化偏誤(Automation Bias):
不要過度相信測試程式或是機器所產生的結果。自動化程式只會檢查你叫它檢查的東西。它看不到版面跑版、看不到顏色太淡讀不清楚、聽不到電腦發出怪聲。
單向思考(Unidirectional Thinking):
開發人員進行測試時,往往只想著「如何證明它能運作(Work)」。但是一個好的測試角色,你必須同時想著「它可能會如何失敗(Fail)」。
歸因謬誤(Fundamental Attribution Error):
不要老是認為「那個工程師就是雷,所以才有 Bug。」需要多元觀察,看看不同狀況和環境。是不是需求一直變?是不是時程太趕?是不是開發工具太難用?
打破測試的迷思
最後,我們要來打破一些業界常聽到的「廢話」。這些話聽起來很有道理,但經不起批判性思考的檢驗。
迷思 1:「每個測試都必須有預期的結果(Expected Result)。」
真相:在探索性測試中,我們常常是為了「學習」軟體行為而測。如果你設限了預期結果,你就看不到那些「意外的驚喜」(通常是 Bug)。
迷思 2:「越早發現 Bug 成本越低。」
真相:不一定。有些功能後來整個被砍掉了,你在需求階段花大把時間找出的邏輯漏洞,修復它的成本就是純浪費。
迷思 3:「測試人員是品質的守門員。」
真相:別傻了,我們攔不住想強行上線的老闆。我們不是守門員,我們是「車頭燈」。我們照亮前方的坑洞,告訴駕駛(專案經理/老闆):前面有坑,你確定要開過去嗎?決定權在他們,告知權在我們。
迷思 4:「您可以管理您無法測量的東西嗎?」
真相:當然可以。你愛你的家人嗎?你能測量「愛」的單位嗎?很多軟體中最重要的特質(易用性、美感、流暢度)都是無法量化的,但至關重要。
你準備好被討厭了嗎?
批判性思考並不容易。當你在會議上問出 "Really?"、"And?"、"So?" 的時候,可能會有人覺得你很煩、在找碴。
但這就是測試人員的價值所在。
軟體開發是一個充滿樂觀主義的世界(我們能做到!我們能準時上線!)。而我們,是這個世界裡專業的懷疑論者。我們點亮燈光,揭示角落裡的蟑螂,不是為了潑冷水,而是為了讓產品在面對真實殘酷的市場之前,先經過我們最嚴苛的思維洗禮。
從今天開始,不要只是「執行測試」。啟動你的系統二,拉開你的批判性距離,問出那些沒人敢問的問題。