從零開始: 測試吧! 前端

sexyoung
進擊的 Front End‘s
9 min readSep 6, 2017
mocha.js

為什麼要測試

料理煮好先試吃,講稿寫完先試講,車子做好也會先經過多次的耐撞與性能測試,其實日常生活中許多我們正在用的東西,都是經過無數測試與考驗,確定了產品的穩定性與品質,最後才會讓我們買到、用到。說測試維護了整個社會的穩定性與安全也不為過XD。

沒有測試遇到的情況

就是東西吃了有人中毒,車子急煞車不靈。以前端來說,就是功能爆掉,無法(或錯使) 使用某某功能,影響小則流量下降,大則減少收益讓產品不再有用使用。通常還沒在寫測試的我們,都交給客戶來幫我們測試。

最後你會在凌晨三點時收到來自公司電話。說客戶在睡前一點測試了一些功能,發現網站竟不跑出來。這樣客戶明早沒辦法跟老闆交待,希望你可以在明天中午前把該功能修正。

然後你匆忙的9點到了公司塞三口把三明治吃掉,一邊喝著冰紅茶一邊趕在中午12點前找出問題並把它修正。結果11點客戶就打來問可以測試了嗎因為老闆在問能不能給他看,所以你咬著牙終於在11點半時把東西交了出去然後把還沒喝完的紅茶一口乾掉。

下午你很自豪的救了今早的火,結果就在準備踏出公司的前一步,AE美眉跟你說客戶很火大,因為中午demo給老闆看的時候竟然出了大包,一堆東西跑不出來,想不到不能跑的東西竟然比可以跑的東西還多! 客戶森77到直接打給老闆,老闆叫AE美眉找出問題後,列一個清單給工程師,並請工程師今天離開公司前一定要處理好。

凌晨三點鐘,你在公司頂樓抽了一根菸,吐出的煙都是這幾年在公司加班的回憶。此時你覺得自己的命好不值錢,於是往下一跳,提早登出了人生。

等等!其實你可以不用登出!

如果你事先就知道測試的存在

它可以預先幫我們測試各種可能的狀況,然後提早幫我們比客戶早一步找到問題並修正。它可以救你的客戶,你的老闆,你的AE美眉,還有你的人生

請你跟我這樣做

首先建立一個資料夾,然後進去後輸入 yarn init 來建立 package.json

mkdir demo && cd demo
yarn init
建立 demo 並進去下個 yarn init

打開編輯器,你的 package.json 應該是這樣地簡單明瞭。

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 可以改

index.js 內容

主程式就叫 add, 內容就很單純的回傳 x + y 的結果,然後注意最後一行:

module.exports = add

這代表如果有其他檔案引入 index.js 這隻檔案,就等同給它 add 方法使用。

安裝 mocha

yarn add mocha -D 即可安裝, -D 代表 安裝的是 開發用套件,程式上線時不會用到的套件mocha 就是測試工具,只有開發會用到。

安裝 mocha

然後你可看到你的 package.json 多了一些東西, devDependencies 裡多了 mocha 這個套件。

package.json 已記錄 mocha 資訊

然後這邊我們需要加入一段程式碼:

加入 scripts test: mocha

意思是稍後我們可以透過 yarn test or npm test 去執行mocha測試。當然,你也可以馬上就試。

沒有寫 test, yarn test 會報錯

如圖所示,因為我們還沒開始寫測試,所以它會跟你說找沒 測試檔。它這邊有特別提到,只要路徑檔名包含 test 的,都會被它視為測試檔。

建立測試檔

因為它會掃描有 test 的資料夾與檔案,所以我建議直接建一個 test 目錄在專案根目錄。然後我們直接在 test 目錄裡建一個 add.spec.js 檔案,內容如下:

test/add.spec.js

檔名叫 add.spec.js 只是方便讓我知道這隻檔案在幫我測試 add 這個方法,其實要叫什麼,也沒有硬性規定。然後你就可以下 yarn test 來看一下結果:

hello test, 0 passing

我們有看到它執行了 console.log 而且 0 passing0 passing代表沒有任何測試通過,因為我們還沒開始寫測試,所以也沒有什麼好通不通過的。

安裝斷言式 chai

mocha 只是只是個測試框架,它可以幫我們建立測試環境,但測試的判定工具,我們之後就簡稱斷言式

yarn add chai -D
安裝斷言式 chai

然後回到 add.spec.js 我們試著寫一段測試看看。

寫一段 expect

第一行我們載入的斷言式expect,等下會由它來判定。
然後 describe 就寫你想測試什麼東西,等下我會把它改成 測試 add
it 適合寫測試實例,這邊可以寫你拿什麼去測試。以上例來說,我預期了 1+2 可以拿到 3 。接著去 yarn test 一下:

1+2預期拿到3

我們可以看到測試有 1 passing 一項通過,很好,也就是 1+2 真的就是 3。接著我們故意寫一段錯誤的預期。

然後 yarn test

預期 8 卻拿到 7

很好,這次就 1 passing 1 failing。剛剛故意寫的錯也報了: 預期拿到8但實際卻拿到 7。它特別標綠色就是 8 是我們的預期。而紅色是實際拿到的結果。由此可見,這次的結果我們有兩種可能:

  1. 參數給錯:把 3 + 4 改掉,改成一個可以給出 8 的運算
  2. 結果給錯:把 8 改成 7

這邊我們就選 2,所以把 8 改成 7 再 yarn test 試試

完美的修正了

這就是傳說中的全綠燈,恭禧測試都通過了。

開始測試 add方法

目前為止,我們只示範 mocha 怎麼建,except 怎麼用,現在我們才要進入主題:測試你寫的程式! 試著把測試檔改成:

測試add方法

把剛剛的測試用 add 方法帶入參數,然後看,預期不變, yarn test

都是預期的結果

然後我們再稍微改一下斷言式:

為預期做各式斷言
跟之前一樣

很好你已經會了初步的測試!! 但…?

我本來就知道結果啊? 為什麼這就叫測試呢?

測試不是應該測試我可能不知道的結果嗎?這樣真的會測到所有可能嗎?

換做法,先寫測試,再寫程式

這次讓我們換個做法,我們先寫測試,再寫程式。這次我們先想一個難一點點的程式好了: x加1 再乘 2 然後減3 再除4。一樣,打開編輯器,寫下我們預先想好的結果:

測試 method1

我們把剛剛的方法先定義另一個檔 method1.js,然後在測試裡先寫好對它的測試,然後 yarn test

method1 不是一個方法

一定會錯,因為我們 method1.js 裡面什麼也沒寫,回到 method1.js ,稍微寫一下:

故意寫錯

然後 yarn test

拿到了一個非預期的結果

綠色是我們預期的結果,紅色是我們實際拿到的結果。很明顯,一定是我們的程式有錯,所以才會冒出這些東西。再讓我們回到 method1 把除4加上去

method1 內容

然後再 yarn test 試試看

剛剛的紅字都變成了綠字

剛剛的紅字變成了綠字。這代表著:我們剛剛之後寫的程式是正確的。是的,寫到這邊相信有感受到一些好處:

  1. 測試檔可以先寫好一堆斷言式,即便要被測的程式根本還沒寫。
  2. 主程式寫好直接看所有的斷言式是否為綠燈。
  3. 主程式未來有修改,測試應該也要過,如果不過,代表主程式可能寫錯。但如果是主程式需求改了,那要改的反而是測試檔。

可是…我的程式好像很難測試?

有些情況,我們會發現自己的程式好像不用給「參數」也沒有「回傳」東西,只是單純的執行一些程序,這時你就會覺得什麼東西也測不出來。這其實代表著程式無法測試,此時應修改它

不能測試的程式不是好程式,回傳結果無法被預期

學習回顧

看完本篇文,你應該會:

  1. 安裝 mocha 與 chai
  2. 知道 mocha 只是測試框架,判定測試要使用斷言式 chai
  3. expect 可以放主程式,它預期要 equal 一個結果。
  4. 先寫測試再寫程式,可以先從需求面得知結果,之後寫主程式也有綠字打勾作為通關依據。

停一下,你可以想更多

測試不是完美的,我們也可能無法列出所有的可能。如果這程式有10種可能,但我們只寫了一個斷言式,到時還是有可能會被測出其他9種錯誤。所以盡可能地,幫我們的程式想多種可能的結果。

當我們站在公司頂樓往下看時,更需要停一下,是否我們過去做了很多不是別人預期的樣子,也許我們過去也在測試別人的耐心,亮了別人的紅燈。調整自己的心態,重構自己看事的角度,試著賞自己一個綠燈吧!

如果這文章有幫助到您,希望您也可以幫我按個讚!謝謝您

--

--