[UT] Angular 召喚 Karma + Jasmine 來做個單元測試吧 I

Huge Gun
6 min readApr 13, 2020

--

這篇是 Unit test 系列的第二篇,主角是三大框架之一的 Angular,會從基礎開始講起,還不會有複雜且特殊的 test case,那…本篇會講到以下幾個重點

  1. Angular 做 UT 需要哪些工具
  2. 這些工具怎麼用
  3. 最基礎的 Test case

如果對 Unit test 觀念名詞上還不瞭解,可參考[第一篇],開始前你可以先 clone code [Github],先說一下整包的架構,主要看 app / case 兩個 folder,app 就如我們熟知的 angular root module 一樣沒變,case 則是對應不同的 test case ,有常見的 component 、service、pipe,每個之下都是獨立元件,且都有 UT file。

大致上說完重要的 folder 架構,接著就正式來了!

Angular 做 UT 需要哪些工具

一般在執行 Unit test 時需要兩個主要的工具,如標題寫的 Karma & Jasmine 他們分別是什麼呢?

Karma = Test runner (testing environment):

快速建構及執行 test code 的環境工具,常見的有: Karma / Jest / Chai 等等… 官方內建的是 Karma

Jasmine = Assertion library (斷言庫):

輔助 Test runner 對錯判定的工具,通常有很多好用的 method 幫助做比對,常見的有: Jasmine / Enzyme / Mocha 等等… 官方內建的是 Jasmine

以上提到的 Karma & Jasmine 兩者都已內建,通常不必再另外裝,本篇使用 Angular 8.2.0 當範例,相應的 library 版本,如下圖:

Karma & Jasmine version

寫 UT code 的檔案,file name 一般是帶有 .spec or .test 兩種其一,Angular cli 產生的通常是 .spec,本篇也是用 .spec,如下圖:

test file name

若你想做 config 相關修改,甚至換其它斷言庫,可參考[這裡] 去調整karma.conf.js 檔,詳細的配置不在本篇範疇內,就先不多說了。

這些工具怎麼用

Karma

執行 Karma 的用法,跟我們熟知使用 library 的方式差不多,一樣是在 package.jsno 添加腳本並運行,例如常見的 run test

"test": "ng test"

啟動了之後,它會尋找我們這包中 file name 帶有 .spec or .test 的檔案,並運行測試最後產出報告結果。

Jasmine

使用測試斷言庫前,它有幾個名詞我們必須先解釋,另外 Jasmine 與 component 相同,有著自己運行時的 life cycle, coding 時也需謹記這些週期跟其特性,如下:

  1. 名詞解釋
  • describe: 一個測試的 block,它是允許巢狀的,可以看成測試容器 or 同隻檔案中,區分不同受測功能的分界線,可以存在單個 or 多個;通常每隻檔案至少有1個 describe,且用來描述測檔案 & 初始化測試。
  • it: 一個測試的最小單位,一般會在 describe 之內,例如: 同個功能中,想測試某個 if else 時,就會有2個 it;通常一個 describe 會有單個 or 多個 it,最少都會有1個。

2. Life cycle

beforeAll

  • 在 run 所有的 describe or specs 前只會 call 一次
  • 掛入整個 global test file 中 需要 initial 的東西

afterAll

  • 在 run 結束所有的 describe or specs 前只會 call 一次
  • 整個 global test file 中 需要 destroy 的東西

beforeEach

  • 在 run 每次測試前都會 call 一次
  • 每個 describe 必需的 common or initial

afterEach

  • 在 run 每次測試後都會 call 一次
  • 每個 describe 需要 destroy 的東西

大致上已經說完使用前的相關小知識跟 life cycle 了,馬上來個最簡單的 case 寫看看吧!!

最基礎的 Test case

我們以最基本的 Counter 來演示一下,你可以在 clone 的這包裡面的case/component/counter 之下找到對應的 file,目前我們的焦點只須放在counter.component.ts & counter.component.spec.ts 這兩隻即可,code 如下:

counter.component.ts

可以看見,就是很單純的有個變數 counter 存目前的數字,分別有加跟減的 function ,以第一篇提到的 UT 5項 rule 來看,就應該要有兩段對應測試 increaseCounter & decreaseCounter 的兩個測試,接著來看看是否真的如此

counter.component.spec.ts

我們依照先前說的 UT 5項 rule & Jasmine life cycle 一項項來看是怎麼回事

  1. 在 beforeEach 每次跑測試之前,執行一次初始化 component ,以保持每段測試都是最開始、最乾淨的狀態。
  2. 在最上層 describe 中,用個 it 來測試這個 component 能否被初始化。
  3. 在子層用第二個 describe 來分區要開始 function 的測試。
  4. 最後用兩個 it,一個 it 一次只測一件事,分別測試兩個 function 的結果是否正確。

以上就是一個最簡單 Angular UT 的例子了,至於上例測試中我們使用到的 toBeTruthy & toBe 都是常用到的 Jasmine matchers,還有更多的 Jasmine 匹配器可以參考[這裡],本篇就不再贅述其餘的 method 了。

其實上例與開發的實際情況還是有落差,下一篇再來講講實際的 component、service、pipe 等等…跟一些較特殊 case 的測試啦!! 感謝

UT 系列:

[UT] What’s unit test ? 在前端要測什麼 ?!

[UT] Angular 召喚 Karma + Jasmine 來做個單元測試吧 I

[UT] Angular 召喚 Karma + Jasmine 來做個單元測試吧 II

[UT] Angular 召喚 Karma + Jasmine 來做個單元測試吧 III

--

--

Huge Gun

槍再大把,沒子彈是不行的;通過學習,鍛造自己的子彈!https://github.com/HsienW