您好,登錄后才能下訂單哦!
小編給大家分享一下怎么為vue的項目添加單元測試,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
動機
單元測試能避免出現一些代碼運行結果與預期不符的錯誤,通常是一些比較低級但又難以發現的問題。
粗心且懶,在每次調整之后,需要不斷地檢查代碼,反復去走流程。擔心由于自己的改動而導致了邏輯上的錯誤。而這里面的一大部分工作其實可以讓單元測試來完成。
有了單元測試之后,可以對代碼本身形成一種規范。如果在進行單元測試過程中發現自己的一些代碼不方便進行測試,那么你可能需要重新審視這些代碼,看是否有一些設計上不合理或者可以優化的地方。
嵌入了單元測試的項目顯得更加的專業,也會更有逼格,測試本身是開發環節需要做的內容。
工具選取對比(一個合適測試框架 -- Jest)
之前也沒有去接觸過前端的單元測試,也是這幾天開始了解,開始并沒有頭緒,所以就在網上以及github上去看了一些之前比較流行的測試框架。發現比較流行的是karma + mocha + Chrome的組合。當我單獨一個個去看的時候,發現其內容還是比較的多的。之后選取了jest也是經過對比權衡的
優點
1、一站式的解決方案,學習成本更低,上手更快(很適合現如今我的需求)
在使用 Jest 之前,我需要一個測試框架(mocha),需要一個測試運行器(karma),需要一個斷言庫(chai),需要一個用來做 spies/stubs/mocks 的工具(sinon 以及 sinon-chai 插件),一個用于測試的瀏覽器環境(可以是 Chrome 瀏覽器,也可以用 PhantomJS)。 而使用 Jest 后,只要安裝它,全都搞定了。
2、全面的官方文檔,易于學習和使用
Jest 的官方文檔很完善,對著文檔很快就能上手。而在之前,我需要學習好幾個插件的用法,至少得知道 mocha 用處和原理吧 我得學會 karma 的配置和命令,chai 的各種斷言方法……,經常得周旋于不同的文檔站之間,其實是件很煩也很低效的事
3、更直觀明確的測試信息提示
4、方便的命令行工具
缺點
jsdom 的一些局限性:因為 Jest 是基于 jsdom 的,jsdom 畢竟不是真實的瀏覽器環境,它在測試過程中其實并不真正的“渲染”組件。這會導致一些問題,例如,如果組件代碼中有一些根據實際渲染后的屬性值進行計算(比如元素的 clientWidth)就可能出問題,因為 jsdom 中這些參數通常默認是 0.
綜上所述,最終我確定下來的方案是使用成熟好用的測試工具庫 --- vue-test-utils 其前身是 avoriaz,avoriaz 也是一個不錯的包,但其 README 中有說明,當 vue-test-utils 正式發布的時候, 它將會被廢棄。 vue-test-utils 能極大地簡化 Vue.js 單元測試。 例如:Vue 單元測試,一般是像下面這樣的(包括 vue-cli 提供的模板里默認也是這樣):
import Vue from 'vue' import HelloWorld from '@/components/HelloWorld' describe('HelloWorld.vue', () => { it('should render correct contents', () => { const Constructor = Vue.extend(HelloWorld) const vm = new Constructor().$mount() expect(vm.$el.querySelector('.hello h2').textContent) .toEqual('Welcome to Your Vue.js App') }) })
使用 vue-test-utils 后,你可以像下面這樣
import { shallow } from '@vue/test-utils' import HelloWorld from '@/components/HelloWorld' describe('HelloWorld.vue', () => { it('should render correct contents', () => { const wrapper = shallow(HelloWorld, { attachToDocument: ture }) expect(wrapper.find('.hello h2').text()).to.equal('Welcome to Your Vue.js App') }) })
可以看到代碼更加簡潔了。wrapper 內含許多有用的方法,上面的例子中所使用的 find() 其中最簡單不過的一個。vue-test-utils 還有 createLocalVue() 等方法以及 stub 之類的功能,基本上可以完成絕大部分情況下的測試用例,這也是非常的實用的了。
安裝使用
安裝使用的方式很簡單,由于想引入到現有的項目中來,現有的項目大多是vue-cli創建的,所以一開始的時候基本上是已經安裝并配置好了 webpack、vue-loader 和 Babel。如果是比較原始的項目,也是可以單獨安裝的。
我們要做的第一件事就是安裝 Jest 和 Vue Test Utils:
$ npm install --save-dev jest @vue/test-utils
然后我們需要在 package.json 中定義一個單元測試的腳本。
// package.json { "scripts": { "test": "jest" } }
在 Jest 中處理單文件組件
npm install --save-dev vue-jest
接下來在 package.json 中創建一個 jest 塊:
{ // ... "jest": { "moduleFileExtensions": [ "js", "json", // 告訴 Jest 處理 `*.vue` 文件 "vue" ], "transform": { // 用 `vue-jest` 處理 `*.vue` 文件 ".*\\.(vue)$": "vue-jest" } } }
具體的使用步驟
此處我根據自己的需求來進行整理
對頁面內容的測試
// viewTest.vue <template> <div class="hello"> <h2>{{ msg }}</h2> <p>1212121</p> </div> </template> <script> export default { name: 'viewTest', data () { return { msg: 'Welcome to Your Vue.js App' } } }
// viewTest.spec import { mount } from '@vue/test-utils' import Component from '../../../src/components/viewTest' describe('頁面展示測試', () => { test('檢查元素是否存在', () => { const wrapper = mount(Component) expect(wrapper.contains('.hello h2')).toBe(true) console.log(wrapper.find('.hello h2').text()) expect(wrapper.text()).toContain('Welcome') }) })
這個是最簡單的對頁面的dom節點的測試,以及可以對文案進行一些測試,這些是比較基礎的
對事件處理的測試
// event.vue <template> <div> <h2>My To Do event</h2> <h3>wawawawawawa</h3> <input v-model="newItem"> <button @click="addItemToList">Add</button> </br> <!--displays event --> <ul> <li v-for="item in listItems">{{ item }}</li> </ul> </div> </template> <script> export default { name: 'event', data () { return { listItems: ['buy food', 'play games', 'sleep'], newItem: '' } }, methods: { addItemToList() { this.listItems.push(this.newItem); this.newItem = ''; } } } </script>
// event.spec.js // 從測試實用工具集中導入 `mount()` 方法 // 同時導入你要測試的組件 import { mount } from '@vue/test-utils' import Component from '../../../src/components/itemEvent' describe('事件觸發測試', () => { test('事件觸發測試', () => { // 現在掛載組件,你便得到了這個包裹器 const wrapper = mount(Component) const button = wrapper.find('button') wrapper.setData({ newItem: '添加測試項', }) button.trigger('click') console.log(wrapper.text()) expect(wrapper.text()).toContain('添加測試項') }) })
這里是在模擬用戶交互的一個測試,當用戶點擊按鈕的時候會把數據插入到當前的列表中來,所以最開始需要定位到這個按鈕,可以用find(),之后要去觸發這個事件, button.trigger('click'),然后把預期的結果,與按照流程的結果相比較,以達到測試的效果。這里模擬的是一個點擊事件,當然,api也支持各種的鼠標事件以及鍵盤事件。
測試異步行為 平時的業務場景中肯定是離不開異步操作的,當發送一個接口請求的時候應該怎么去才做。Jest 運行測試用例同時可以模擬了 HTTP 庫 axios,對預期結果可以進行設定和比較,比如:
// axios.js export default { get: () => Promise.resolve({ data: 'response' }) }
<template> <div> <button @click="fetchResults">發送請求</button> {{value}} </div> </template> <script> import axios from '../axios.js' export default { data () { return { value: '初始值' } }, methods: { async fetchResults () { const response = await axios.get('mock/service') this.value = response.data console.log(this.value) } }, created (){ console.log(axios.get) } } </script>
// async.spec.js import { shallowMount } from '@vue/test-utils' import async from '../../../src/components/async' jest.mock('axios') it('當點擊按鈕發送請求時檢驗返回值', () => { const wrapper = shallowMount(async) console.log(jest) wrapper.find('button').trigger('click') // expect(wrapper.value) expect(wrapper.vm.value).toBe('response') // console.log(wrapper.vm.value).toBe('初始值') })
這個時候運行的話會報錯誤
因為斷言在 fetchResults 中的 Promise 完成之前就被調用了,所以value的值還是最開始的初始值。大多數單元測試庫都提供一個回調來使得運行期知道測試用例的完成時機。Jest 和 Mocha 都是用了 done。我們可以和 $nextTick 或 setTimeout 結合使用 done 來確保任何 Promise 都會在斷言之前完成。
以上是“怎么為vue的項目添加單元測試”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。