教你如何編寫Vue.js的單元測試的方法


Vue.js是一個JavaScript框架,可用於構建Web應用程序的前端框架。特別是在創建復雜功能時,對於每個項目,有必要在我們的應用程序中查看所有內容,並檢查它是否符合預期。然而,對於大型項目,每次新的更新后,檢查每個功能將變得很麻煩。因此,我們可以創建可以一直運行的自動化測試,並保證我們的代碼可以正常運行。在本文中,我們將為VueJS創建一些簡單的單元測試。

要進行測試,我們將先制作一個基本的待辦事項列表組件。我們將測試該列表是否正確顯示,並且用戶可以將新項目添加到待辦事項列表中。希望在本教程結束之前,您可以編寫測試,檢查您的組件輸出給用戶,以及通過與HTML進行交互來模擬用戶操作(例如通過單擊按鈕)。

本文中的所有代碼可以在 Github 下載。

搭建環境

搭建JavaScript項目可能是一個復雜的過程。有那么多庫需要選擇,所有這些庫的目的都略有不同。幸運的是,對於VueJS,我們有vue-cli,它為我們設定了一切!您需要首先安裝npm,然后可以運行以下命令:

?
1
2
npm install -g vue-cli
vue init webpack project-name

在這個階段,你會被提示幾個問題。大多數都可以直接繼續,您可以選擇默認選項,唯一的要求是您回答YES以包括vue-router和YES來設置Karma和Mocha的單元測試。然后安裝依賴項:

?
1
2
cd project-name
npm install

這個最終命令將啟動您的瀏覽器並打開localhost運行您的應用程序:

?
1
npm run dev

下面是對vue-cli為我們設置的一些關鍵依賴關系(非常重要)的簡要概述,包括為我自己的項目安裝的版本。

依賴

Webpack (v2.3) 是一個捆綁器,它結合了各種JavaScript,CSS,HTML(和其他)文件,使他們可以隨時由客戶端處理。
Babel (v6.22) 是ECMAScript 6到ECMAScript 5的編譯器。這些是不同的JavaScript標准,目前的瀏覽器不能解析所有的ECMAScript 6,因此需要進行轉換。

測試依賴關系

Karma (v1.4) 是一個測試運行器,它運行一個Web服務器,其中包含項目的應用程序代碼,並對其執行測試。

Mocha (v3.2) 是JavaScript的測試框架。
Chai (v3.5) 是可以與Mocha一起使用的斷言庫。

在您的項目中,您應該能找到以下文件夾:build,config,node_modules,src,static和test。對本文來說,重要的是src,它將保存我們的應用程序代碼並進行test。

我的第一個測試

一個好的開始需要去做一些基本工作。我們將從創建簡單列表組件開始。在src/components文件夾中創建一個名為List.vue的新文件,並將以下代碼放在里面:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
  <div>
   <h1>My To Do List</h1>
   </br>
   <!--displays list -->
   <ul>
    <li v- for = "item in listItems" >{{ item }}</li>
   </ul>
  </div>
</template>
  
<script>
export default {
  name: 'list' ,
  data () {
   return {
    listItems: [ 'buy food' , 'play games' , 'sleep' ],
   }
  }
}
</script>

在組件中,列表項存儲在組件數據中的數組(listItems)中。然后可以在模板中訪問該數據,並在foreach循環中循環(v-for),並顯示在頁面上。

為了使我們的列表看起來更有趣,我們可以創建一個新的路徑來顯示我們的組件。進入src/router/index.js並添加路由,你的代碼應該是這樣的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import List from '@/components/List'
  
Vue.use(Router)
  
export default new Router({
  routes: [
   {
    path: '/' ,
    name: 'Hello' ,
    component: Hello
   },
   {
    path: '/to-do' ,
    name: 'ToDo' ,
    component: List
   },
  ]
})

現在,如果您導航到localhost:8080/#/to-do,您將在瀏覽器中看到您的列表效果!

首先我們要測試數據是否正確顯示。在 test/unit/specs 下創建一個新的文件List.spec.js並放上如下代碼:

?
1
2
3
4
5
6
7
8
9
import List from '@/components/List' ;
import Vue from 'vue' ;
  
describe( 'List.vue' , () => {
  
  it( 'displays items from the list' , () => {
    // our test goes here
  })
})

在這個文件中,我們描述List.vue組件,我們有一個單獨的空測試,它將檢查它(組件)是否從列表中顯示項目。這是Mocha測試的基本文件結構。

在我們的測試中,我們首先需要設置Vue組件。復制下面的代碼,並將其放在注釋“our test goes here”的位置:

?
1
2
3
// build component
const Constructor = Vue.extend(List);
const ListComponent = new Constructor().$mount();

我們擴展Vue然后安裝我們的組件。安裝組件很重要,因為這是在我們的模板中呈現HTML。這實際上意味着HTML被構建,並且我們的模板中的變量(例如{{item}})被填滿數據,使得我們可以訪問HTML(通過$el)。

隨着我們的組件准備好,我們可以寫第一個斷言。在這個例子中,我們使用了'expect'風格,由Chai斷言庫提供,以及'should'和'assert'。 安裝組件后放置以下代碼:

?
1
2
// assert that component text contains items from the list
expect(ListComponent.$el.textContent).to.contain( 'play games' );

如上所述,我們可以使用ListComponent.$el獲取組件的HTML,並且使用ListComponent.$el.textContent只訪問內部HTML(即文本)。斷言是檢查文本是否包含在組件數據中設置的列表項之一。

為了檢查一切都能正常工作,我們可以運行測試!使用vue-cli項目,我們可以簡單地輸入npm run unit,這是一個別名 cross-env BABEL_ENV = test karma start test/unit/karma.conf.js --single-run。

?
1
npm run unit

如果所有的測試都已經通過,它將顯示綠色,並顯示成功測試和代碼覆蓋率報告的列表,讓您知道在測試期間執行的應用程序代碼的百分比。

模擬用戶輸入

這是一個很好的開始,但是很少有應用程序只會顯示數據。我們要添加的下一個功能是讓用戶能夠在其列表中添加新項目。為此,我們需要一個輸入框,用戶可以在其中鍵入新項目,並在按鈕上添加項目到列表中。這是List.vue的更新版本:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<template>
  <div>
   <h1>My To Do List</h1>
   </br>
   <input v-model= "newItem" >
   <button @click= "addItemToList" >Add</button>
   <!-- displays list -->
   <ul>
    <li v- for = "item in listItems" >{{ item }}</li>
   </ul>
  </div>
</template>
  
<script>
export default {
  name: 'test' ,
  data () {
   return {
    listItems: [ 'buy food' , 'play games' , 'sleep' ],
    newItem: ''
   }
  },
  methods: {
    addItemToList() {
     this .listItems.push( this .newItem);
     this .newItem = '' ;
    }
  }
}
</script>

使用v-model,輸入框的值綁定到存儲在組件數據中的newItem變量。當單擊按鈕時,將執行addItemToList函數,將newItem添加到列表數組中,並清除newItem,以便可以將更多的內容添加到列表中。

要開始測試此功能,請在List.spec.js中創建一個新的空測試,並添加測試代碼:

?
1
2
3
it( 'adds a new item to list on click' , () => {
   // our test goes here
})

首先我們要構建我們的組件,並模擬一個用戶在輸入框中輸入的內容。由於VueJS將輸入框的值綁定到newItem變量,所以我們可以簡單地將我們的值設置為newItem。

?
1
2
3
4
5
6
// build component
const Constructor = Vue.extend(List);
const ListComponent = new Constructor().$mount();
  
// set value of new item
ListComponent.newItem = 'brush my teeth' ;

接下來我們需要點擊按鈕。我們必須在HTML中找到這個按鈕,它可以使用$el。只有這一次,我們才可以使用querySelector來查找實際的元素。可以使用它的類(.buttonClass),其id(#buttonId)或元素的名稱(button)來找到一個元素。

?
1
2
// find button
const button = ListComponent.$el.querySelector( 'button' );

為了模擬一個點擊,我們需要將按鈕傳遞給一個新的事件對象。在測試環境中,List組件不會監聽任何事件,因此我們需要手動運行監視器。

?
1
2
3
4
// simulate click event
const clickEvent = new window.Event( 'click' );
button.dispatchEvent(clickEvent);
ListComponent._watcher.run();

最后,我們需要檢查newItem是否顯示,我們已經知道如何從第一個測試中完成!我們可能還想檢查newItem是否存儲在列表數組中。

?
1
2
3
//assert list contains new item
expect(ListComponent.$el.textContent).to.contain( 'brush my teeth' );
expect(ListComponent.listItems).to.contain( 'brush my teeth' );

以下是完整的測試文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import List from '@/components/List' ;
import Vue from 'vue' ;
  
describe( 'List.vue' , () => {
  it( 'displays items from the list' , () => {
   const Constructor = Vue.extend(List);
   const ListComponent = new Constructor().$mount();
   expect(ListComponent.$el.textContent).to.contain( 'play games' );
  })
  
  it( 'adds a new item to list on click' , () => {
   // build component
   const Constructor = Vue.extend(List);
   const ListComponent = new Constructor().$mount();
  
   // set input value
   ListComponent.newItem = 'brush my teeth' ;
  
   // simulate click event
   const button = ListComponent.$el.querySelector( 'button' );
   const clickEvent = new window.Event( 'click' );
   button.dispatchEvent(clickEvent);
   ListComponent._watcher.run();
  
   // assert list contains new item
   expect(ListComponent.$el.textContent).to.contain( 'brush my teeth' );
   expect(ListComponent.listItems).to.contain( 'brush my teeth' );
  })
})

現在我們可以再次運行我們的測試,應該會顯示綠色!

希望這段代碼對你來說能夠很清楚,但是它不是特別容易理解,特別是對於第一次進行VueJS測試的人來說。有一個VueJS實用程序庫,其中包含了一些更復雜的外觀代碼。要使用它,我們可以轉到我們的項目根目錄並運行以下命令:

?
1
npm install avoriaz

現在我們可以隱藏mount()之后的Vue組件的設置,並且為了單擊按鈕,我們需要的是兩行代碼:find()該按鈕和dispatch() )點擊事件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { mount } from 'avoriaz' ;
import List from '@/components/List' ;
import Vue from 'vue' ;
  
describe( 'List.vue' , () => {
  // previous tests ..
  
  it( 'adds new item to list on click with avoriaz' , () => {
     // build component
   const ListComponent = mount(List);
  
   // set input value
   ListComponent.setData({
    newItem: 'brush my teeth' ,
   });
  
   // simulate click event
   const button = ListComponent.find( 'button' )[0];
   button.dispatch( 'click' );
  
   // assert list contains new item
   expect(ListComponent.text()).to.contain( 'brush my teeth' );
   expect(ListComponent.data().listItems).to.contain( 'brush my teeth' );
  })
})

總結

我個人認為寫作測試對於我的正常工作流程至關重要,但是使用JavaScript,特別是VueJS,我開始碰到一些麻煩。希望本教程將幫助任何與我一樣遇到麻煩的人!

本文中的所有代碼可以在 Github 下載。 

 

 
Typescript視頻教程  ...2
node基礎入門+就業實戰視頻教程+源碼
珠峰Node.js全棧開發  ...2
愛創課堂—web 前端視頻教程
基於MUI的原生API調用跨平台APP開發入門與實戰全套完整版  ...2
手把手教你做爬蟲---基於NodeJs
前端大牛第一步源碼分析及修Bootstrap框架
NodeJs+mongodb全棧工程師實戰聊天系統
2017 最新JavaScript初級+中級+ 高級+面試全套視頻教程  ...2
2017最新徹底征服React Native跨平台APP實戰京東商城項目實戰視頻教程+源碼  ...2
基於nodejs爬蟲的信息采集並展示的桌面APP
2017最新 阿里前技術專家十三年編程老司機 帶你徹底征服JavaScript  ...2345
2017全新全棧高級工程師實戰課程Vue+Node+MongoDB(完結) attach_img
Vue 實戰 APP 之番薯 在線觀看
2017 最新JavaScript初級+中級+ 高級+面試全套視頻教程
NodeJs+mongodb全棧工程師實戰聊天系統視頻教程 attach_img
東方耀 手把手教React Native實戰開發視頻教程+源碼筆記 1-237集  ...2
HTML5高級前端視頻教程
Vue.JS多套精華視頻教程合集 Web界面框架Vue.JS 五套中文+英文視頻教程+資料
Angular 4.0從入門到實戰 打造股票管理網站 attach_img


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM