jest-vue前端自動化測試實踐04—vue項目之TDD&BDD
- 2019 年 11 月 1 日
- 筆記
jest-vue前端自動化測試實踐04—vue項目之TDD&BDD
[toc]
Write By CS逍遙劍仙 我的主頁: www.csxiaoyao.com GitHub: github.com/csxiaoyaojianxian Email: sunjianfeng@csxiaoyao.com
本節程式碼地址 https://github.com/csxiaoyaojianxian/JavaScriptStudy 下的自動化測試目錄
1. 項目構建
本節將以 TDD 的方式來搭建一個 TodoList 的 vue 項目。如何搭建包含 jest
的 vue
項目已經在第一節 jest-vue前端自動化測試實踐01
中已經進行過介紹,其中,在 jest
的配置文件 jest.config.js
中,需要注意 testMatch
配置項,它指定了測試用例文件的路徑,這裡我們習慣性設置為 __tests__
文件夾下的以 .test
加多種後綴結尾的文件。
testMatch: [ '**/__tests__/**/*.test.(js|jsx|ts|tsx)' ]
在配置過啟動命令 "test:unit": "vue-cli-service test:unit --watch"
後就可以愉快地以 watch
方式將 jest 在 shell 中實時運行起來,每次修改程式碼後,jest 都會自動執行測試用例。
$ npm run test:unit
2. 項目目錄結構
項目的目錄結構組織如下:
├── src │ ├── sssets │ ├── containers │ │ └── TodoList │ │ ├── __mocks__ 測試mocks文件 │ │ ├── __tests__ 測試用例文件 │ │ │ ├── unit 單元測試 │ │ │ │ └── TodoList.test.js │ │ │ └── integration 集成測試 │ │ │ └── store.test.js │ │ ├── components 子組件 │ │ │ ├── Header.vue │ │ │ └── UndoList.vue │ │ │ │ │ └── TodoList.vue TodoList父vue組件 │ │ │ ├── utils │ │ └── testUtils.js 存放測試工具公共工具 │ ├── App.vue vue-App │ └── main.js 入口文件 │ ├── public ├── jest.config.js jest配置文件 ├── ... └── package.json
3. vue 組件測試方法
3.1 組件淺渲染和深渲染
在 vue 項目中測試 vue 組件,vue 官方提供了 @vue/test-utils
工具用於測試 vue 組件,其中包含 mount
和 shallowMount
方法,用於渲染 vue 組件。
import { mount, shallowMount } from '@vue/test-utils'
不同的是,mount 方法會渲染完整的組件,包括子組件,適合 BDD 和集成測試,而 shallowMount 方法只會渲染當前組件,因此速度更快,效率更高,更加適合 TDD 和單元測試。為了方便獲取測試需要的 DOM 元素,可以將獲取 DOM 元素的方法進行封裝,在 testUtils.js
中定義 findTestWrapper
方法如下:
export const findTestWrapper = (wrapper, tag) => { return wrapper.find(`[data-test="${tag}"]`) }
3.2 vuex 的使用
可以通過在 mount 中傳入 vuex 對象實現對 vuex 的引用:
import store from '@/store' const wrapper = mount(TodoList, { store })
3.3 組件非同步測試
對於非同步請求,可以使用 vue 的 vm.$nextTick
方法實現非同步數據的渲染。
4. TDD & BDD
在 TDD 中,由於是測試驅動開發,因此往往先進行需求分析再根據需求編寫測試用例,最後才進行項目業務邏輯編碼滿足用例,因此用於單元測試,而 BDD 則相反,在編寫完業務邏輯程式碼後編寫測試用例,因此是從功能角度出發,更加適合集成測試,具體程式碼可以見 github:
本節程式碼地址 https://github.com/csxiaoyaojianxian/JavaScriptStudy 下的自動化測試目錄
4.1 組件
對於 vue 測試工具渲染出的組件,自動化測試,我們一般可以考慮生成快照監測dom結構變化進行測試。還可以測試組件中方法是否觸發,以及查找其子組件等。
expect(wrapper).toMatchSnapshot() // 生成快照 wrapper.emitted().add // 組件中 add 方法是否被觸發 wrapper.find(Header) // 查找子組件 Header
4.2 vm 實例
大部分的自動化測試,都是通過 vm 實例上的 data 變化來測試的,可以獲取對應的 data 值,也可以通過 vm 調用相關方法。
wrapper.vm.$data.inputValue // 獲取 inputValue wrapper.vm.addUndoItem('csxiaoyao') // 執行 addUndoItem 方法 wrapper.vm.$emit('add', content) // 觸發外部 add 方法
4.3 jsDom 操作
jest 提供了一套 node 環境下的 dom,在獲取到指定的 dom 元素後,可以對 dom 元素執行各種操作:
const input = findTestWrapper(wrapper, 'input') input.exists() // 獲取dom存在性 input.setValue('csxiaoyao') // 給dom賦值 input.trigger('keyup.enter') // 觸發dom方法 input.trigger('change') // 觸發dom方法
4.4 vuex
vuex 數據操作
store.state.inputValue // 數據獲取 store.commit('changeInputValue', 'csxiaoyao') // 數據設置
4.5 非同步操作
定時器測試,可以藉助 vm.$nextTick
方法和 jest 定時器操作實現
beforeEach(() => { jest.useFakeTimers() }) it(` 1. 用戶進入頁面時,等待 3s 2. 列表應該展示遠程返回的數據 `, (done) => { const wrapper = mount(TodoList, { store }) // 傳入 store jest.runAllTimers() wrapper.vm.$nextTick(() => { const listItems = findTestWrapper(wrapper, 'list-item') // 不能直接判斷,因為非同步操作在 mounted 之後 expect(listItems.length).toBe(2) done() }) })
