Kevlin Henney
測試必要行為,而非附帶行為#
測試中一個常見的陷阱是假設實作的具體細節就是你要測試的內容。乍看之下,這似乎是優點而非陷阱。但換個方式表述,問題就更明顯了:一個常見的陷阱是將測試硬編碼(hardwire)到實作的具體細節上,而這些細節是附帶的(incidental),與所需功能毫無關係。
偽陽性的代價#
當測試硬編碼到實作的附帶細節時,與所需行為實際相容的實作變更可能導致測試失敗,產生偽陽性(false positive)。程式設計師通常會重寫測試或重寫程式碼來回應。假設偽陽性其實是真正的問題,往往是出於恐懼、不確定或懷疑——這實際上會把附帶行為提升為必要行為的地位。
在重寫測試時,程式設計師可能做兩件事:
- 重新對焦測試到必要行為上(好的做法)
- 直接硬編碼到新的實作上(不好的做法)
避免過度指定#
以下幾種情況特別容易過度指定:
- 比較函式的具體回傳值:例如 Java 的
String.compareTo或 C 的strcmp,規格只要求負數、正數或零,但程式設計師常誤以為-1和+1就是規格要求 - 格式化和排版細節:除非你在寫 XML 產生器等以格式為核心的程式,否則間距、排版不應影響測試結果
- UI 控制項的位置:硬編碼按鈕和標籤的位置會減少日後調整的彈性
白盒測試的問題#
過度指定的測試常出現在**白盒測試(whitebox testing)**中。白盒測試以程式碼結構來決定測試案例,典型的失敗模式是測試最終只是在斷言程式碼做了程式碼做的事——只是重述已經從程式碼中顯而易見的事實,不提供任何進展感或安全感。
有效的測試應該像**合約義務(contractual obligation)而非鸚鵡學舌。測試需要以黑盒(blackbox)**視角看待被測單元,以可執行的形式勾勒出介面合約。因此,請將測試對齊到必要行為上。