跳至主要内容

[Day24] 談談寫測試的好處:從為你自己寫測試開始

前幾週主要都在談 TypeScript,對我來說 TypeScript 最重要的是能增加程式的可維護性,就和 ESLint 一樣,用或不用程式都能運行,一開始用可能有點痛,但用一段時間後會發現對於程式品質和可維護性有相當程度的提升,而可維護性的提升就是在幫助自己也幫助他人。

除了 TypeScript 之外,另一個我認為能夠提升程式維護性的就是寫測試(Testing),但筆者並非那種什麼都要加上測試的開發者,以前端來說我也不確定什麼都加上測試會不會是最適當的,因為前端有許多 UI 的操作,不同的 Component 之間可能也會有互動上的關聯,在不同開發階段選擇不同的測試方式,或許才會是最有彈性和適切的。

無論如何,我都相當鼓勵大家去學習如何撰寫測試,特別是從為你自己寫測試開始。

為你自己寫測試

「為你自己寫測試」這句偷用了龍哥(高見龍)的書名—「為你自己學 git」、「為你自己學 Ruby on Rails」,但我認為寫測試的第一步的確是要為了自己而寫,因為「程式是你寫的,而你必須為你自己寫的程式負責」。

我知道許多讀者一定因為開發時程有限的緣故,覺得需求都做不完了,怎麼會有時間寫,這個我們後面再來聊,今天先著重在寫測試的好處。

避免自己沒想到的錯誤

不論是自己寫程式時,或是 code review 看別人的程式碼時,相信許多開發者一定有過這樣的經驗—「用看的沒問題,跑下去就壞了」,程式在執行時並非總是如我們預期,有時你信心滿滿,想說只是改這個應該不用再測一次,結果部署上去後,卻馬上遇到當初沒想到的問題。

舉例來說,你可能寫了一個 function,單純就是把兩個價格相加,但你沒想到 API 回傳的竟然是字串,帶入你寫好的那個 function 後就壞了。

或者,如果你有刷題的經驗,一定也有過那種,以為自己寫的解法沒問題,結果按下 submit 後發現有自己沒考慮到的 case。

透過測試你有機會提早發現到問題,不必等到 code review 時他人提醒,或正式上線後才發現問題。或者,你雖然有寫測試,但一開始沒有寫到這樣的測試案例,你也可以再問題發生後補到 test case 中,防止後續這個問題再次發生。

未來改動程式碼時更有信心

不知道讀者有沒有過這種感覺,當程式越來越複雜時,你開始有點不安,你不太確定你之前寫好的業務邏輯是否還能正常運作。或者,當你試著改變以前寫好的程式,也許是需要添加功能,或者你發現有更好的寫法,但在要改的時候,你感到有點不安,因為很多地方都曾經有呼叫過這個函式,你不確定現在這樣改,原本的功能是否會壞掉。

在「大規模重構」這本書中,作者也提到重構的第一步是要先確定即將修改的部分已經有撰寫測試,否則不要貿然重構,因爲沒有完整測試的話,有很高的可能會在渾然不知的情況下,把原本好的功能給改壞了,但卻依然很開心地繼續重構的...。

一旦有了測試,不論是在需求變更、添加功能、或重構時都能夠更有信心。

為他人測試

程式即文件,輔助文件的不足

開發者在接手程式或使用他人寫好的工具時都需要文件。寫文件的問題不在於需要花額外的時間來寫,而在於後續對這份文件的更新和維護。很常見的情況是,一開始開發好功能後因爲還很有熱情,所以文件會寫的很齊,但後續有可能再修改功能後忘了回頭去更新文件,或是後續接手的人沒有意識到要回頭改文件,導致久而久之,這份文件就過期了,然後過期越久,這份文件的價值就越低。

上述的情況很常發生在開發的是自家產品時,因為常常是自己人能夠看懂就好。

相較於每次提醒開發者有變更時就要記得要去更新文件,筆者更喜歡的是「程式即文件」,或是用程式輔助文件這件事,這也是筆者相當喜歡 TS 的原因之一,因為在定義型別時,等於就是在告訴未來的使用者,這個功能可以怎麼用。

同樣的,測試也可以扮演輔助文件的這個功能,在寫測試時,你會需要實際執行該方法,間接的也是在示範這個功能可以怎麼被使用,預期會得到什麼結果。

有些時候官方文件的說明如果寫的不夠詳細或範例不夠多時,筆者就會去看這個套件寫的測試檔,因為測試檔中就會列出這個函式能夠怎麼樣被使用,預測會得到什麼結果的許多範例。

小結

「為你自己寫測試」最重要的是讓自己對於自己寫的程式更有信心,未來在修改時,也可以比較不擔心自己會不會把原本好的功能給改壞了。

「為他人寫測試」則是讓接手程式碼或使用該工具的人能夠更快了解這個程式要怎麼使用。

然而,不論是「為你自己寫測試」或「為他人寫測試」,你會發現最後受益的都還是自己,因為「三個月後的自己就是別人」,三個月後回過頭來看當初自己寫的程式時,常常會忘了這段當初為什麼要這樣寫,甚至忘了這段是自己寫的都有可能,這時候如果有測試的範例或其他方式來讓自己更快理解這段程式碼,不也就幫助到了自己?

什麼時候要寫測試呢?問問自己,這裡加上測試後能夠帶給自己好處嗎?如果答案是肯定的,要不要就為了自己來加上測試呢?