Kevlin Henney
精確且具體地測試#
測試一段程式碼時,重要的是測試其所需的、本質的行為,而非特定實作的附帶行為。但這不應該被當作寫模糊測試的藉口。測試需要既準確(accurate)又精確(precise)。
排序的例子#
排序演算法是一個經典的說明案例。當程式設計師被問到「你會測試什麼?」時,最常見的回答是:「排序的結果是一個已排序的序列。」雖然這是對的,但這不是完整的事實。更精確地加入條件後,許多人會補充:結果序列的長度應該與原始序列相同。雖然正確,但這仍然不夠。
例如,給定序列 3 1 4 1 5 9,以下序列滿足「非遞減排序且長度相同」的後置條件:
3 3 3 3 3 3
這顯然不是預期的結果!完整的後置條件(postcondition)是:結果必須是已排序的,而且是原始值的一個排列(permutation)。
測試應具可讀性#
即使正確地陳述了後置條件,這也不足以構成一個好測試。好的測試應該是可讀的、可理解的、簡單到能一眼看出是否正確。除非已有現成的程式碼可以檢查排序和排列,否則測試程式碼很可能比被測程式碼更複雜。如 Tony Hoare 所觀察的:
建構軟體設計有兩種方式:一種是使其簡單到顯然沒有缺陷,另一種是使其複雜到沒有明顯的缺陷。
使用具體範例#
使用**具體範例(concrete example)**能消除這種意外的複雜性。例如,給定序列 3 1 4 1 5 9,排序的結果是 1 1 3 4 5 9。沒有其他答案可以替代。
具體範例有助於以直觀且明確的方式說明一般行為:
- 將一個元素加入空集合的結果,不只是「集合非空」——而是集合現在有一個元素,且該元素就是加入的那個
- 向表格新增一列的結果,不只是「表格大了一列」——還必須能透過該列的 key 取回該列
在指定行為時,測試不應只是準確,還必須精確。