1 of 51

Vue.js 單元測試使用 Jest

larry du

2020/11

2 of 51

工具1 - Jest

Jest 是由 facebook 開源的一款測試框架其特色是簡單好上手。

2

3 of 51

Jest API - describe

describe 創造一整個區塊,裡面包含許多測試用例 (test case),表示一組相關的測試。

3

4 of 51

Jest API - test/it

test/it 區塊稱為測試用例,表示一個單獨的測試,是測試中的最小單位。

(這兩個是可以互換的alias)

4

5 of 51

Jest API - expect

expect (斷言)判斷源碼的實際執行結果與預期結果是否一致,如果不一致就拋出一個錯誤。

5

6 of 51

測試結果

6

7 of 51

工具2 - Vue test utils

Vue.js 的官方單元測試函式庫。

提供許多 API開發者測試 Vue.js例如:

mount、shallowMount、exists、find、setData、setProps 等等

7

8 of 51

安裝

1.使用 Vue CLI 添加 (前提該專案是 Vue CLI 創的)

$ vue add @vue/unit-jest

2.手動設定

請參考文件

3.教練,我想寫 TS 版本

拿去

8

9 of 51

跑測試的指令

第一行是跑完剛剛的第一個指令就會自動添加的

下面兩行分別是: 持續跑測試、更新快照測試檔案(晚點會講)

第二行指令跟第一行差別在於,下這個指令,當修改完測試就會再跑一次測試,方便邊改邊測,對於正在撰寫測試時很有幫助。

9

10 of 51

寫第一個測試 (1/3)

步驟一: 引用組件

10

11 of 51

寫第一個測試 (2/3)

步驟二: 掛載組件(使用 Vue test utils)

11

12 of 51

寫第一個測試 (3/3)

步驟三: 斷言結果(使用 Jest)

12

13 of 51

執行測試

13

14 of 51

兩種渲染方式 mount & shallowMount 的差異

mount 會忠實呈現子組件。

shallowMount 會將組件中的子組件替換為存根 (stub,你可以想像是一個毫無反應的假組件)

14

mount 渲染結果

shallowMount 渲染結果

15 of 51

兩種渲染方式 mount & shallowMount 的比較

mount

  • 速度較慢
  • 測試範圍廣
  • 貼近使用者真實情況

shallowMount

  • 速度較快
  • 測試較獨立
  • 較不貼近使用者真實情況

15

兩者並沒有好壞之分,各有適合的地方

16 of 51

測試 Props / data 語法

掛載組件時的第二個參數可以傳遞 options,傳入 propsData or data 即可進行測試

16

17 of 51

測試 Props 範例

17

18 of 51

案例 - 模擬使用者輸入

18

19 of 51

測試程式

19

案例 - 模擬使用者輸入

20 of 51

單元測試的三步驟

1.Arrange 安排–設置測試對象並準備測試的先決條件。

2.Act 行動–執行測試的實際工作。

3.Assert 斷言–驗證結果。

20

21 of 51

套用單元測試三步驟

21

安排

行動

斷言

案例 - 模擬使用者輸入

22 of 51

Vue 的非同步更新 - 使用 await 解決

使用 await wrapper.vm.nextTick() 或者直接在非同步更新前使用

例如: await wrapper.vm.setValue(‘123’)

可以(需要)被 await 的方法有:

setData、setValue、setChecked、setSelected、setProps、trigger

22

23 of 51

但資料都是 call API 來的呀?

23

案例 - 模擬使用者輸入

24 of 51

使用 mocking 模擬依賴對象的行為並替換掉它

24

25 of 51

更真實的例子

25

案例 - 模擬使用者輸入

26 of 51

Jest Mock axios

26

27 of 51

更真實的測試程式

27

案例 - 模擬使用者輸入

28 of 51

使用 wrapper.emitted() 測試自定義事件 (emit)

28

29 of 51

測試 Vuex

29

30 of 51

單獨測試 getters

30

31 of 51

測試組件中的 getters

這個組件直接把 getters 寫在 template 中用

31

32 of 51

  1. 使用 createLocalVue,建立獨立的 vue 實體(避免污染 原本的 vue實體)
  2. 準備 state 及 payload
  3. 掛載組建的時候,將 vuex store & vue 傳入掛載的組件,藉此 mock store
  4. 斷言結果

32

33 of 51

單獨測試 mutations

單獨測試 mutation 也很簡單,重點在於輸入跟輸出

33

34 of 51

  • import mutations
  • 準備 state 及 payload
  • call mutation
  • 斷言結果

34

35 of 51

測試組件中的 mutations

  1. 創造 localVue ,localVue 再去使用 Vuex
  2. mock mutation
  3. 建立 store

35

36 of 51

測試組件中的 mutations - 使用 localVue

4. shallowMount 組件並混入 store & localVue

5. 觸發 mutations 事件

6. 斷言 mutation 函式被觸發

36

37 of 51

單獨測試 action

37

38 of 51

38

39 of 51

39

40 of 51

測試組件中的 actions 使用 mocks

  1. mock 一個 store
  2. 掛載組建的時候用 mock 去替換 $store
  3. 觸發 actions 事件
  4. 斷言 mutation 函式被觸發

40

41 of 51

Vuex 測試總結

1. vuex 測試方式可分為兩種,使用 localVue 或使用 mock ,並無優劣之分

2. mock 要測試的對象以外的行為,例如 state, payload 等等

3. getters、mutations 測試相當容易,因為他們就像一般的 JS 函式,只要設好輸入與輸出就差不多了

4. actions 稍微麻煩一點,需要 mock API & 判斷 mutations 是否正確觸發

5. 若要判斷 mutation or function 是否被觸發一樣是使用 jest mock 的方式, state & payload 用寫死的變數去模擬即可

41

42 of 51

vue router

來不及準備

42

43 of 51

偷懶的好幫手?-- 快照測試

安裝

$ npm install --save-dev jest-serializer-vue

設定

jest.config.js

module.exports = {

snapshotSerializers: ["jest-serializer-vue"],

};

43

44 of 51

快照測試 - toMatchSnapshot()

44

45 of 51

快照測試 - 流程

45

46 of 51

快照測試 - 更新快照檔

"test:unit:update": "vue-cli-service test:unit -u"

全部更新

$ npm run test:unit:update

部分更新

1.$ npx vue-cli-service test:unit -u -t="${file name}"

2.$ npm run test:unit:watch 之後按 i 進入互動模式選擇檔案

46

47 of 51

推薦文件

47

48 of 51

感謝收看!

48

咦?好像還有一個重要的沒說

49 of 51

整合 CI/CD

加這行進去!

npm run test:unit

49

50 of 51

Q & A

50

51 of 51

感謝收看

51