科技新知

測試場 VS 自動化測試

筆者一直地更新自己過去所編寫的程式,很恐怖的是,那時的自己很少思考過怎樣寫測試Test Case。致使每次做更新時,都膽戰心驚,要手動建立測試場,人肉去測試每個可能有受影響的地方。在那些年的時候,有能力自己搭建測試場,已經是萬幸。但當面對一些要長期維護的程式,測試場的人肉測試並不是一個有效的方法,一來費時間,二來人腦記憶並不可靠。單靠自己去想想那些地方受影響,再測試,某程度是在挑戰人腦的記憶上限。如果是團隊合作,就更麻煩,你以為修改不會影響到其他人,結果卻是翻天覆地。

所以為求長治久安,編寫自動化測試,是有必要的。這些自動化測試,都算是回歸測試,每次程式有任何地方改動,都確保所有自動化測試被通過。理想始終是理想,但實際操作又會遇到怎麼的問題?

以筆者剛更新的程式為例,難以測試主要是當初沒有想過要測試這件事,所以程式結構通常是【連續順序】地執行。想分段測試?除非先重構。

Function中太多自己創建的Object

回顧自己的程式,初期編寫時,總會我手寫我心,每想要創建任何資源,在java中就會使用 new 字眼,或是自行呼叫某些 builder 類來取得資源,這是其中一個令自己無法寫測試的原因。

我們要想想,這些資源,是不是自己Function中所關心的核心。如果這個資源是被直接回傳的,我們要保留,如果它是HttpClient,只是要來獲取其他資源的媒介,我們或許可以利用依賴注入來取得它,即是把 HttpClient 改為經呼叫方傳入。注入的好處時,我們可以在Test中,修改那些資源的行為和結果。更進一步的是,把那些資源改為 interface 的方式存取,那麼在 Test 中就能更任意地控制該資源的行為。

首次重構某些資源成為依賴注入,大部份都會影響呼叫方,很多地方都要重寫。不論使用constructor injection, setter injection, annotation injection 等,上傳呼叫方,或多或少都會要加減改變參數。極致地,我們把構建都交給Program 框架去做,例如Spring Boot中,各種資源,都交給框架去自動配致。當然,這種做法的學習成本高,除錯成本也高。

【注入】其實是想在控作那些資源,在測試中運行得到固定的行為。使用前述的HttpClient例子,當我們業務邏輯是先訪問外部Web API,再根據結果做處理,那麼我們測試時,就會想模擬Web Api的結果。如果要做到自動化測試,最強硬的手段,就修改自己的HttpClient,模疑給出固定結果。

想要做到這種,在傳統的Java中,我們需要透過進一步抽離Interface去做。但這樣做很累,所以筆者通常會用如Mockito的程式庫,去修改HttpClient的行為。有興趣直接看程式碼的讀者,可以去看 github

當然,上述的 HttpClient 例子,使用測試場也有可做測試,自己再去模擬那些Web Api的回傳,有些情況下,這樣會更真實,但大家就必需好好定義測試場的行為。因為測試場可能與團隊的其他成員所共用,有機會其他人可能想要更多互動的測試方式,而非固定的結果。但並上非固定結果的測試場,自動化要測試的可控度就減少。

馬交野


獵金•遊戲
4DX  28年後
英語版  馴龍記
4DX    馴龍記
4DX  英語版  馴龍記
榴心風暴
IMAX with Laser 罪人們
野黨
器子
劇場版 我與機器子
大風殺
那些年的我們
超異能特攻
英語版  史迪仔
私家偵探
IMAX with Laser 馴龍記 英語版
拼命三郎
殺神John Wick之芭蕾殺姬
不赦之罪
MX4D 職業特工隊:最終清算
斷背山 20週年獻映 3rd MIQFF
史迪仔 英語版
殺神JOHN WICK外傳:芭蕾殺姬
罪人們
28 年後
獵狐行動
關於我和鬼變成家人的那封利是
職業特工隊:最終清算
馴龍記
28年後
史迪仔
死神來了:血脈
獵金•遊戲
4DX  28年後