把輸入依照某條規則改變,輸出應該依照對應的規則改變——metamorphic testing 驗的就是這組對應,而不是任何一次執行的答案。搜尋條件加上一個更嚴格的過濾,結果集應該是原本的子集;把所有商品的價格同乘以二,總價也該同乘以二;在圖片上加一點雜訊,分類結果不該翻轉。這條「輸入怎麼變、輸出就該怎麼變」的對應稱為變形關係,它讓測試在沒有任何一次執行的正確答案可查的情況下仍然成立——這是繞開 oracle problem 最後一層的手段,比不變量的要求更低。

概念位置

三種判準的要求由強到弱排成一條線:逐例斷言要知道每個輸入的正確輸出,不變量只要知道輸出必須滿足什麼,變形關係連這個都不需要、只要知道輸入變了輸出該怎麼變。變形關係因此是三者裡門檻最低、也是最後一道還寫得下來的判準。完整的退階表與選用程序在判準寫不下來的時候,來源分類見 test oracle

它跟參照實作 oracle 的差別在於不需要第二份實作:變形關係比較的是同一份實作的兩次執行,因此在只有一個實作可用的場景(多數自研系統)仍然適用。

可觀察訊號與例子

「跑出來的結果對不對,沒有人說得準;但如果它變成那樣,就一定是錯的」——講得出這句話的時候就到了變形關係的位置。推薦排序、搜尋相關度、路徑規劃、稅務與費率試算、以及模型輸出的穩定性,都落在這一類——最終答案的正確性難以逐例判定,而輸入輕微改動後輸出翻轉是可以斷定的異常。

關係的方向要跟著業務語意選。搜尋條件收緊時結果集該縮小是子集關係;商品清單順序打亂時結果集該完全相同是置換不變關係;兩者同時成立,而各自抓的是不同的缺陷——前者抓過濾邏輯,後者抓對輸入順序的隱性依賴。

設計責任

變形關係要從需求推導,不是從實作觀察。從實作跑兩次看到某個對應成立就把它寫成斷言,等於把實作現在的行為當成規格,這與出處不獨立的失效是同一件事;正確的來源是業務語意上「本來就該如此」的那些對應。

關係被破壞時的歸因需要額外一步。逐例斷言變紅指向一個具體的輸出值,變形關係變紅只說明兩次執行的關係不對,缺陷可能在任一次執行裡;縮小範圍的做法是把一條複合關係拆成幾條單步關係,讓每次只改變一個輸入維度。