It is wrong to suppose that if you can’t measure it, you can’t manage it. —— Peter Drucker
從事軟體工作多年後,雖然還是很仰賴各種指標,但也能跳脫指標去思考現狀,就像軟體測試這樣的工作,易懂難精,怎麼在不同場景中找到有代表性的事件(或指標),對管理來說,可能會更重要一點,就像這次要談的主題———可測試性,就是一個非常容易被忽略,卻是SQA核心觀念的重中之重,也是為什麼很多團隊常常在品質這件事上掙扎卻苦尋不到方法的主要原因之一。
想吃東坡肉,卻得自己養豬
一個常見的例子是通知信流程。當使用者完成一筆訂單,系統會寄出一封「訂單完成通知信」。這封信通常是事件觸發,但不論是哪種,我們的測試目標常常是「驗證通知信格式與內容是否正確」—— 問題就來了。
如果系統把「交易完成」與「通知寄送」兩件事緊耦合(沒有獨立介面或觸發機制),那 QA 為了驗證信件內容,就必須不斷建立真實訂單。這種測試方式成本高、效率差,也很難重現邊界條件。
換句話說,我們其實是想測後段的「通知模組」,但卻被迫一再執行前段的「交易流程」才能引發事件。這不是流程錯,而是測試邏輯無法解耦,導致整個流程的「可測試性」大幅下降。
這樣的設計在多個系統中都很常見,也正是為什麼我們常說:測試難,不是因為場景複雜,而是因為沒有給測試一個簡單入口。
更麻煩的是你不能自己養豬
前面的場景中,如果系統設計成強綁定的情況下,我們又不能完全控制訂單的生成時,那這樣的測試就會變得更難深入,測試範圍也會進一步被限制住。
以電子發票通知為例,某系統設計為:使用者在完成第一筆交易,且成功填寫發票載具時,系統會寄送一封歸戶成功通知信。
縱然產品需求如此,如果研發沒有在重置交易筆數或是否成功填寫發票載具這些條件中,提供簡易的方式達成,對測試來說,就會非常麻煩:我們只想測那封通知信是否會在對的條件下寄出、且內容是否正確,卻被迫每次都要從註冊帳號、下單、付款、填載具一路重做一次。更麻煩的是,有些條件一旦觸發就無法再重現,例如「首次交易」這類邏輯,就必須一直製造乾淨帳號來測。
這種系統設計把前段流程與後段行為緊密綁死,沒有提供任何切點、mock、或測試入口讓我們可以單獨驗證某個模組的邏輯與行為,最後的結果是:測試不只是成本高,而是根本無法在有限時間內做到全面覆蓋。
可測試性,不只是能不能測,而是代價多高
從這些例子來看,我們會發現,問題通常不在「測不測得了」,而在於「要付出多大的代價才能測」。
如果每次測一封通知信,都要先完成一筆真實交易,那測試的成本就不是驗證邏輯,而是重演流程。如果想測某個後段模組,卻得依賴另一個系統或部門的資料、排程、甚至實體條件,那測試的效率與完整性早已被架構綁死。
可測試性的核心,其實不是「你有沒有寫測試」,而是「這個系統有沒有提供讓你低成本驗證的能力」。
在實務上,一個很具代表性的例子是保險系統對接。我們常看到一個情況:開發完成後,等到真正與上游保險核心系統對接時,才發現許多參數、欄位、錯誤碼、時序邏輯與原本預期不同,這才回頭調整實作。每次對接都像盲測,試一次修一次,一來一往往往耗費數週甚至更久。
但為什麼不在開發階段就先驗證好自己的邏輯?很多研發人員會說:我們不知道對方會怎麼回應。這正是可測試性不足的核心表現 —— 當系統本身缺乏模擬機制、回應注入點、錯誤情境覆蓋能力時,就算我們願意測,也根本測不出什麼。
測試不是等一切接起來才開始,而是從系統一開始設計時,就該問自己:我寫的這段邏輯,有沒有辦法被單獨驗證?
這句話聽起來像是在談單元測試,但實際上,它更關乎系統的設計思維 —— 一段邏輯是否有機會在不依賴其他流程的情況下被驗證,是衡量整個系統可測試性的關鍵之一。
單元測試是實踐的方式,但真正該思考的,是我們寫的邏輯有沒有暴露出「可以被測」的介面與條件。
測試從來就不只是工程問題
需求可以很複雜,邏輯也可以很細緻,這本來就是產品該處理的價值。但問題在於,這些功能在被設計時,是否有一起設計「要怎麼驗證它」?
當需求定義時沒有考慮驗證方式,開發階段也沒有提供測試介面,測試階段自然就無法有效驗證。這時候,測不深不是因為 QA 不夠努力,也不是因為工程師偷懶,而是這個功能從一開始就沒打算讓人能好好驗證。
所以對產品開發團隊來說,更好的是:產品設計時,把驗證方式也設計進去。這不代表每個需求都要附帶 test plan,但至少該問一句:「這個邏輯,之後要怎麼測?」
當這樣的思維成為習慣,產品才真正具備品質可控性;否則就只能靠經驗豐富的工程師幫忙補上缺口,而這往往是不穩定、不可複製的解法。
後記:為什麼要寫這篇文章?
會寫這篇,是因為我們注意到一個明顯的趨勢:在最近這一季的新客戶中,有超過一半,都是因為內部測試效率不振,才主動來找我們協助。
但在實際評估之後,我們發現問題的根源並不在測試團隊或測試方法上,而是系統本身的可測試性太低。流程難以拆解、邏輯沒有切點、資料不可控制,讓測試人員就算再努力,也很難驗證關鍵邏輯。
更困難的是,這種問題通常無法被測試團隊自己說清楚。因為他們不是不想測,而是根本沒有地方可以下手。做得很辛苦,但成果總是不如預期。
這種情況實在太普遍了,我們只能說,願天下沒有難測的系統,如果真的難,找我們聊聊。