科學計算實務:軟體、驗證與可重現性

回歸測試(regression testing)

你花了一週調校程式,終於在一個困難的問題上得到正確答案,然後就繼續往前。兩個月後,你「改良」了程式中一個不相干的部分——卻在沒注意到的情況下,又把那個困難的問題弄壞了。回歸測試正是抓住這種情況的安全網:一組自動化測試,在每次改動後重跑,以確認程式仍產生它以前產生的結果,好讓一個「回歸」(以前能動、現在不能動的東西)被立即抓到,而不是在很久之後才痛苦地被發現。

在機制上,一個回歸測試把一個已知良好的輸出釘住,並拿現行的程式去對照它。你在一個固定的輸入上執行程式,存下你信任的那個答案(有時稱為黃金母版或基準),測試就重跑那個輸入並作比較。對數值程式有個關鍵的微妙之處:你幾乎從不測試浮點數的「精確」相等,因為捨入誤差、不同的 BLAS,或一個被重新排序的求和,都可能合法地改變最後幾位數字。你改為斷言新結果落在離基準一個聲明的容差之內——例如,相對誤差低於 1e-10。測試通常接進持續整合(CI),這樣每次提交都自動觸發整套測試,而失敗會在改動被合併之前被標示出來。這與單元測試(檢查一個小函數對照已知答案)以及驗證(檢查正確性對照真實數學)不同:回歸測試防範的是「改變」,確保今天的程式碼與昨天受信任的程式碼一致。

回歸測試是可信任數值軟體的安靜支柱之一,它與可重現性及標竿天然成對:一個被凍結的標竿答案,正是理想的回歸基準。誠實的告誡都圍繞著容差。設得太緊,整套測試就會對每個無害的浮點抖動發出狼來了的警報,訓練團隊去忽略失敗;設得太鬆,一個真正讓精度劣化的臭蟲就會悄悄溜過去。選擇容差是一種判斷,應反映問題實際的精度需求。還有個微妙的陷阱:回歸測試只認證答案沒有「改變」——若你的基準一開始就是錯的,整套測試就會忠誠地永遠保護那個錯誤答案。回歸測試保存行為;它不確立正確性,那是驗證的工作。

一個求解器的回歸測試,為一個固定問題存下基準結果,並在任何程式編輯後重新計算,斷言 abs(new - baseline) / abs(baseline) < 1e-10,而非 new == baseline。當一次重構意外地在某一項裡把 + 換成了 -,測試會在下一次 CI 執行時失敗,並直接指向那個回歸——在幾分鐘內被抓到,而非幾個月。

在一個容差內把新輸出與一個受信任的基準比較——絕不要對浮點數測試精確相等。

回歸測試只證明答案沒有改變,而非它曾經是對的。若基準是錯的,整套測試就會忠誠地守護那個錯誤答案。確立正確性是驗證的工作,不是回歸測試的工作。

又称
regression test suitegolden-master testing回歸測試套件回溯測試