從零開始: 測試吧! 前端
為什麼要測試
料理煮好先試吃,講稿寫完先試講,車子做好也會先經過多次的耐撞與性能測試,其實日常生活中許多我們正在用的東西,都是經過無數測試與考驗,確定了產品的穩定性與品質,最後才會讓我們買到、用到。說測試維護了整個社會的穩定性與安全
也不為過XD。
沒有測試遇到的情況
就是東西吃了有人中毒,車子急煞車不靈
。以前端來說,就是功能爆掉,無法(或錯使) 使用某某功能,影響小則流量下降,大則減少收益讓產品不再有用使用
。通常還沒在寫測試的我們,都交給客戶來幫我們測試。
最後你會在凌晨三點時收到來自公司電話。說客戶在睡前一點測試了一些功能,發現網站竟不跑出來。這樣客戶明早沒辦法跟老闆交待,希望你可以在明天中午前把該功能修正。
然後你匆忙的9點到了公司塞三口把三明治吃掉,一邊喝著冰紅茶一邊趕在中午12點前找出問題並把它修正。結果11點客戶就打來問可以測試了嗎因為老闆在問能不能給他看,所以你咬著牙終於在11點半時把東西交了出去然後把還沒喝完的紅茶一口乾掉。
下午你很自豪的救了今早的火,結果就在準備踏出公司的前一步,AE美眉跟你說客戶很火大,因為中午demo給老闆看的時候竟然出了大包,一堆東西跑不出來,想不到不能跑的東西竟然比可以跑的東西還多!
客戶森77到直接打給老闆,老闆叫AE美眉找出問題後,列一個清單給工程師,並請工程師今天離開公司前一定要處理好。
凌晨三點鐘,你在公司頂樓抽了一根菸,吐出的煙都是這幾年在公司加班的回憶。此時你覺得自己的命好不值錢,於是往下一跳,提早登出了人生。
等等!其實你可以不用登出!
如果你事先就知道測試的存在
它可以預先幫我們測試各種可能的狀況,然後提早幫我們比客戶早一步找到問題並修正。它可以救你的客戶,你的老闆,你的AE美眉,還有你的人生
。
請你跟我這樣做
首先建立一個資料夾,然後進去後輸入 yarn init
來建立 package.json
mkdir demo && cd demo
yarn init
打開編輯器,你的 package.json
應該是這樣地簡單明瞭。
- name: 應該就沒什麼好說的,就專案名稱
- version: 預設都是 1.0.0 但我建議一開始從
0.1.0
- main: 主程式檔案,等等說
- license: 沒意外就 MIT
撰寫主程式
我們的主程式很簡單,就寫一個加法。規格如下:
add(x, y) = x + y
也就是我給 x 跟 y 參數,它應該要回傳 x + y 給我
。趕快來寫一下主程式。還記得剛剛 package.json
裡的 main
內容是什麼嗎?就是 index.js
!代表主程式指向專案目錄裡的 index.js
,目前沒有,那就建一個,並寫好內容:
main 指向的 index.js 可以改
主程式就叫 add, 內容就很單純的回傳 x + y 的結果,然後注意最後一行:
module.exports = add
這代表如果有其他檔案引入 index.js
這隻檔案,就等同給它 add
方法使用。
安裝 mocha
用 yarn add mocha -D
即可安裝, -D
代表 安裝的是 開發用套件
,程式上線時不會用到的套件
。 mocha
就是測試工具,只有開發會用到。
然後你可看到你的 package.json
多了一些東西, devDependencies
裡多了 mocha
這個套件。
然後這邊我們需要加入一段程式碼:
意思是稍後我們可以透過 yarn test
or npm test
去執行mocha
測試。當然,你也可以馬上就試。
如圖所示,因為我們還沒開始寫測試,所以它會跟你說找沒 測試檔
。它這邊有特別提到,只要路徑檔名包含 test
的,都會被它視為測試檔。
建立測試檔
因為它會掃描有 test 的資料夾與檔案
,所以我建議直接建一個 test 目錄在專案根目錄。然後我們直接在 test 目錄裡建一個 add.spec.js
檔案,內容如下:
檔名叫 add.spec.js
只是方便讓我知道這隻檔案在幫我測試 add
這個方法,其實要叫什麼,也沒有硬性規定。然後你就可以下 yarn test
來看一下結果:
我們有看到它執行了 console.log
而且 0 passing
, 0 passing
代表沒有任何測試通過,因為我們還沒開始寫測試,所以也沒有什麼好通不通過的。
安裝斷言式 chai
mocha 只是只是個測試框架
,它可以幫我們建立測試環境,但測試的判定工具,我們之後就簡稱斷言式
。
yarn add chai -D
然後回到 add.spec.js
我們試著寫一段測試看看。
第一行我們載入的斷言式expect
,等下會由它來判定。
然後 describe
就寫你想測試什麼東西,等下我會把它改成 測試 add
。it
適合寫測試實例,這邊可以寫你拿什麼去測試。以上例來說,我預期了 1+2 可以拿到 3
。接著去 yarn test
一下:
我們可以看到測試有 1 passing
一項通過,很好,也就是 1+2 真的就是 3
。接著我們故意寫一段錯誤的預期。
然後 yarn test
很好,這次就 1 passing 1 failing
。剛剛故意寫的錯也報了: 預期拿到8但實際卻拿到 7
。它特別標綠色就是 8 是我們的預期。而紅色是實際拿到的結果。由此可見,這次的結果我們有兩種可能:
- 參數給錯:把 3 + 4 改掉,改成一個可以給出 8 的運算
- 結果給錯:把 8 改成 7
這邊我們就選 2,所以把 8 改成 7 再 yarn test 試試
這就是傳說中的全綠燈,恭禧測試都通過了。
開始測試 add方法
目前為止,我們只示範 mocha
怎麼建,except
怎麼用,現在我們才要進入主題:測試你寫的程式!
試著把測試檔
改成:
把剛剛的測試用 add
方法帶入參數,然後看,預期不變, yarn test
然後我們再稍微改一下斷言式:
很好你已經會了初步的測試!! 但…?
我本來就知道結果啊? 為什麼這就叫測試呢?
測試不是應該測試我可能不知道的結果嗎?這樣真的會測到所有可能嗎?
換做法,先寫測試,再寫程式
這次讓我們換個做法,我們先寫測試,再寫程式。這次我們先想一個難一點點的程式好了: x加1 再乘 2 然後減3 再除4
。一樣,打開編輯器,寫下我們預先想好的結果:
我們把剛剛的方法先定義另一個檔 method1.js
,然後在測試裡先寫好對它的測試,然後 yarn test
一定會錯,因為我們 method1.js
裡面什麼也沒寫,回到 method1.js
,稍微寫一下:
然後 yarn test
綠色是我們預期的結果,紅色是我們實際拿到的結果。很明顯,一定是我們的程式有錯,所以才會冒出這些東西。再讓我們回到 method1 把除4加上去
然後再 yarn test
試試看
剛剛的紅字變成了綠字。這代表著:我們剛剛之後寫的程式是正確的
。是的,寫到這邊相信有感受到一些好處:
- 測試檔可以先寫好一堆斷言式,即便要被測的程式根本還沒寫。
- 主程式寫好直接看所有的斷言式是否為綠燈。
- 主程式未來有修改,測試應該也要過,如果不過,代表主程式可能寫錯。但如果是主程式需求改了,那要改的反而是測試檔。
可是…我的程式好像很難測試?
有些情況,我們會發現自己的程式好像不用給「參數」也沒有「回傳」東西,只是單純的執行一些程序,這時你就會覺得什麼東西也測不出來。這其實代表著程式無法測試,此時應修改它
。
不能測試的程式不是好程式,回傳結果無法被預期
學習回顧
看完本篇文,你應該會:
- 安裝 mocha 與 chai
- 知道 mocha 只是測試框架,判定測試要使用斷言式 chai
- expect 可以放主程式,它預期要 equal 一個結果。
- 先寫測試再寫程式,可以先從需求面得知結果,之後寫主程式也有綠字打勾作為通關依據。
停一下,你可以想更多
測試不是完美的,我們也可能無法列出所有的可能。如果這程式有10種可能,但我們只寫了一個斷言式,到時還是有可能會被測出其他9種錯誤。所以盡可能地,幫我們的程式想多種可能的結果。
當我們站在公司頂樓往下看時,更需要停一下,是否我們過去做了很多不是別人預期的樣子,也許我們過去也在測試別人的耐心,亮了別人的紅燈。調整自己的心態,重構自己看事的角度,試著賞自己一個綠燈吧!