學習了一段時間 Vue 組件單元測試相關知識,感覺比起用什么測試框架、怎么寫測試更重要的是搞明白組件測試應該測什么,這里就總結一下自己的一些思考。
組件測試不應該測什么
-
單純測試組件模板中的 HTML
比如,測試組件模板中有幾個
div、input、button,以及元素的class、id屬性等與業(yè)務邏輯無關的純 UI 測試。這里并非說我們不需要關注組件的 UI,而是出于以下幾個考量: -
測試組件的內部方法
如果一些方法只是在組件內部調用其他方法而沒有任何暴露給外部的行為(比如更改了組件的 UI、請求外部 API 等),那這些方法是不需要測試的。我們希望一個組件就像一個黑盒一樣,我們不關心其內部的處理邏輯而只關注其外部呈現(xiàn)。
You should test your component's public interface and side effects.
組件測試應該測什么
這里以 Vue 組件來總結一下組件測試需要測什么。
-
測試組件是一個 Vue 實例
test("is a Vue instance", () => { const wrapper = shallowMount(MyComponent); expect(wrapper.isVueInstance()).toBeTruthy(); });這個測試應該置于該組件所有其他單元測試之前,以保證該組件能夠正常掛載
-
測試組件實例的數(shù)據(jù)
由于組件的渲染是依賴
props、data以及計算屬性computed的,因此需要針對這些數(shù)據(jù)進行測試,如- 給定
props下,初始的data是否正確 - 給定
props和data后,計算屬性的值是否正確 - 在父組件中測試
props是否正確傳遞給子組件
- 給定
-
測試組件實例的渲染結果
同樣因為組件的渲染依賴
props、data、computed這些數(shù)據(jù),因此需要 mock 這些數(shù)據(jù)來測試不同數(shù)據(jù)作用下的渲染結果是否符合預期,如測試本文內容是否與數(shù)據(jù)一致
-
測試條件渲染的結果
元素或子組件的存在性是否隨數(shù)據(jù)的變化而變化
-
測試循環(huán)渲染的結果
元素或子組件的數(shù)量是否與數(shù)據(jù)一致
-
測試組件實例的事件
用戶與 UI 的交互是通過事件完成的,因此需要針對事件進行測試,如
-
觸發(fā)
click、input等事件后組件上的自定義事件是否被觸發(fā)比如 Todo List App 的
add-todo等一系列自定義事件能否被觸發(fā) -
觸發(fā)事件后對應的處理方法是否被調用,以及是否使用預期的參數(shù)調用
需要注意的是,這里主要測試的是一些對外的方法,比如調用 API 等
觸發(fā)事件后
data是否按預期更新-
觸發(fā)事件后組件是否按預期渲染
如果已經(jīng)有測試用例測試過事件能更新
data、且組件能根據(jù)data渲染,則無需再測試組件能根據(jù)事件渲染
-
使用 Vuex 管理數(shù)據(jù)的組件應該怎么測
使用 Vuex 管理數(shù)據(jù)流后,我們需要額外針對getters、mutations、actions等進行測試,以保證組件的數(shù)據(jù)和行為是符合我們預期的。針對 Vuex 的測試有兩個要點:
由于
getters、mutations、actions實際上都是普通的函數(shù),因此我們可以通過測試這些函數(shù)在給定輸入下是否有預期輸出來保證它們的正確性-
結合Vuex 的作用原理,我們可以按照 Vuex 中數(shù)據(jù)的流向設計測試用例
一個由 Vuex 管理數(shù)據(jù)流的 App 大致是按照如下的方式工作的:
- 用戶與 UI 交互觸發(fā)事件
- 事件的監(jiān)聽函數(shù) dispatch 相應的
action -
action提交包含類型和數(shù)據(jù)的mutation -
mutation負責處理具體的業(yè)務邏輯,更新 App 的state -
getters進而會根據(jù)state重新計算 - 組件監(jiān)聽到
state的變化而重新渲染
在理解上述要點的情況下,我們可以總結出針對 Vuex 的一些測試方法:
- 模擬事件的觸發(fā),測試是否 dispatch 相應的
action - mock 掉
commit方法,測試action函數(shù)是否能使用正確的參數(shù) commitmutation - 測試給定參數(shù)下,
mutations能否正確修改state - 測試給定
state時,getters的計算結果是否正確 - 給定
state和getters下,測試組件接收到的props是否正確 - 給定
props下組件能否正確渲染
怎么使用快照測試
上述總結的單元測試方法主要測試的是組件的行為是否與預期相符,為了更全面的測試組件 UI,我們可以使用快照測試。
快照測試帶來的好處是可以清晰的對比出 UI 的變化,讓開發(fā)人員確認是必要的改變還是引入的 bug,避免了為測試 UI 導致單元測試過于陷入細節(jié)和脆弱。
需要注意的是,快照測試是不能夠替代單元測試的,因為它只是對 UI 歷史版本的記錄,無法用于描述所期望的 App 的行為,因而不能夠像傳統(tǒng)的單元測試一樣做為所開發(fā)的 App 的“使用文檔”,它應該和單元測試一起互為補充。