前端單元測試,以及給現有的vue項目添加jest + Vue Test Utils的配置

 文章原址: https://www.cnblogs.com/yalong/p/11714393.htmlcss

背景介紹:

之前寫的公共組件,後來須要添加一些功能,添加了好幾回,每次修改我都要測試好幾遍保證之前的功能不受影響,有次我測試遺漏致使組件出現bug,並且因爲是公共組件,我每次修改還得讓其餘小夥伴更新組件,非常麻煩,因此必定要寫測試, 對本身負責,也是對他人負責!html

前端測試介紹

1.單元測試(unit測試)
單元測試是把代碼當作是一個個的組件,從而實現每個組件的單獨測試,測試內容主要是組件內每個函數的返回結果是否是和指望值同樣。
2.端到端測試(e2e測試)
e2e測試是把咱們的程序堪稱是一個黑盒子,我不懂你內部是怎麼實現的,我只負責打開瀏覽器,把測試內容在頁面上輸入一遍,看是否是我想要獲得的結果。前端

二者的存在都是頗有意義的:vue

unit測試是程序員寫好本身的邏輯後能夠很容易的測試本身的邏輯返回的是否是都正確。
e2e代碼是測試全部的需求是否是均可以正確的完成,並且最終要的是在代碼重構,js改動不少以後,須要對需求進行測試的時候測試代碼是不須要改變的,你也不用擔憂在重構後不能達到客戶的需求。node

對於公共組件單元測試就能夠知足基本需求了,本文也只講單元測試。webpack

單元測試的好處

  • 減小bug
  • 提升代碼質量
  • 快速定位問題,減小調試時間
  • 單元測試仍是一份很好的業務文檔,每項測試的描述均可以體現業務邏輯
  • 下降人工測試的成本,雖然編寫及維護測試腳本須要付出額外的成本,但從長遠來看,這些成本一般遠比採用人工測試要低地多
  • 保證該庫在後續的開發維護過程當中不會出現意料以外的問題;在修改代碼「好比優化、重構、修改或添加新的功能等」後,每每須要從新進行測試,這時人工測試一般沒法保證覆蓋到每個測試點,這時就會爲項目帶來隱患

不過不是全部的代碼都要寫單元測試,由於寫單元測試也是有必定工做量的,對於更新頻繁,變化較快的需求,讓前端寫測試,他估計會崩潰。可是對於公共組件,或者其餘比較穩定的業務組件,單元測試是頗有必要的。ios

採用 jest + Vue Test Utils進行單元測試的緣由

1.Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所須要的全部測試工具,配置較少,對vue框架友好。git

2.Vue Test Utils 是 Vue.js 官方的單元測試實用工具庫,爲jest和vue提供了一個橋樑,暴露出一些接口,讓咱們更加方便的經過Jest爲Vue應用編寫單元測試。程序員

3.vue-cli 默認的單元測試也是使用的這套方案github

對於不瞭解Vue Test Utils 的同窗能夠先看這裏 VueTestUtils, 想了解Jest 的同窗能夠看這裏 Jest

在現有項目中添加(Jest + Vue Test Utils)的測試環境

爲了演示配置的過程, 我用vue-cli 初始化了一個簡單的項目,webpack 是4.0

項目代碼地址: 點我

1.安裝依賴
npm i @vue/test-utils babel-jest jest jest-serializer-vue jest-transform-stub vue-jest -D
個人項目安裝好以下:

image.png 

2.修改.babelrc配置
在根目錄的.babelrc中添加以下配置

"env": {
    "test": {
      "presets": ["env"]
    }
  }

就變成了以下(項目自己的配置不用改)

{
  "presets": [
    ["env", { "modules": false }]
  ],
  "env": {
    "test": {
      "presets": ["env"]
    }
  }
}

3.創建測試文件目錄
在根目錄下創建test目錄,test裏面再按照以下創建對應文件,文件夾,圖上的紅字是註釋


image.png

4.添加jest配置,jest.conf.js內容以下,相關屬性的解釋也寫在了註釋裏

const path = require('path');

module.exports = {
    verbose: true,
    testURL: 'http://localhost/',
    rootDir: path.resolve(__dirname, '../../'),
    moduleFileExtensions: [
        'js',
        'json',
        'vue'
    ],
    moduleNameMapper: {
        '^@\/(.*?\.?(js|vue)?|)$': '<rootDir>/src/$1',   // @路徑轉換,例如:@/components/Main.vue -> rootDir/src/components/Main.vue
        '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/test/unit/__mocks__/fileMock.js', // 模擬加載靜態文件
        '\\.(css|less|scss|sass)$': '<rootDir>/test/unit/__mocks__/styleMock.js'  // 模擬加載樣式文件   
    },
    testMatch: [ //匹配測試用例的文件
        '<rootDir>/test/unit/specs/*.spec.js'
    ],
    transform: {
        '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
        '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
    },
    testPathIgnorePatterns: [
        '<rootDir>/test/e2e'
    ],
    // setupFiles: ['<rootDir>/test/unit/setup'],
    snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
    coverageDirectory: '<rootDir>/test/unit/coverage', // 覆蓋率報告的目錄
    collectCoverageFrom: [ // 測試報告想要覆蓋那些文件,目錄,前面加!是避開這些文件
        // 'src/components/**/*.(js|vue)',
        'src/components/*.(vue)',
        '!src/main.js',
        '!src/router/index.js',
        '!**/node_modules/**'
    ]
}

備註:

單元測試的思想是單純的測試組件,對於樣式,圖片等這些靜態資源是不予測試的,因此上面的配置中才有了對這些靜態資源進行了模擬加載,否則Jest + Vue Test Util 這倆哥們解析不了scss, css, img..這些靜態資源,測試就跑不起來了。
同時對於組件內引用的外部資源,也須要模擬,好比axios,下面的測試代碼裏面有處理的演示。

5.給測試添加eslint配置,test/unit/ 目錄下的.eslintrc內容以下

{
  "env": { 
    "jest": true
  }
}

6.__mocks__文件目錄下創建 fileMock.js,用來處理測試中遇到的靜態資源, 內容就一行代碼

module.exports = 'test-file-stub';

 

  1. specs下寫測試用例代碼,像下圖所示(組件名+spec):
          image.png
  1. package.json 的 scripts 裏添加測試命令
"unit": "jest --config test/unit/jest.conf.js --coverage"

執行 npm run unit 就能夠啓動測試了,測試完畢會產生相似下圖的報告, 測試覆蓋率,測試用例,鏡像..都有

image.png

編寫測試用例

先看下我演示的項目,以下

image.png

checkbox 開關控制圖片的顯隱
表單請求有驗證,點擊當即建立觸發表單驗證,驗證經過提交表單;點擊重置按鈕去掉驗證提示。

個人組件就兩個

image.png

一個 Form.vue 一個  Main.vue, 就對這倆個組件測試。

測試用例寫了三個,以下

image.png

裏面詳細的代碼我就不貼出來了,能夠去項目源碼裏面看。
下面說下寫這幾個測試用例須要注意的地方
1.因爲項目用到了 element-ui 因此在寫測試用例的時候,也須要給模擬的 Vue(createLocalVue) install element-ui
關鍵部分的代碼以下:
import { mount, createLocalVue  } from '@vue/test-utils'
const localVue = createLocalVue()
import ElementUI from 'element-ui'
localVue.use(ElementUI)

import Form from '@/components/Form'

// 測試表單請求
describe('Test Form Request', () => {
  it('Form Request Sucess', () => {
    let wrapper = mount(Form, {
      stubs: {
        transition: false
      },
      localVue
    })
  })
})

 

2.checkbox切換的時候,控制圖片顯示/隱藏,須要用nextTick

it('show switch img', () => {
    wrapper.setData({ switchvalue: true })
    // 修改完數據 dom操做沒同步 須要用 nextTick
    return Vue.nextTick().then(function() {
      expect(wrapper.findAll('.logoImg').length).toBe(1)
    })
  })

3.模擬axios
爲何要模擬axios ?

由於Jest + Vue Test Utils這套環境中是沒有 axios的,因此他不認 axios, 可是組件代碼裏面確實調用了axios, 那麼咱們就須要模擬一個 axios 出來

新建 axios.js 文件

image.png
 
axios.js 的內容以下:
module.exports = {
    get: jest.fn(() => Promise.resolve({ status: 200 }))
}

 

我這裏只用到了 status: 200,你們根據本身需求設置返回的數據。
測試用例代碼以下:

import { mount, createLocalVue  } from '@vue/test-utils'
import Vue from 'vue'
const localVue = createLocalVue()
import ElementUI from 'element-ui'
localVue.use(ElementUI)
import axios from 'axios'

import Form from '@/components/Form'

// 測試表單請求
describe('Test Form Request', () => {
  it('Form Request Sucess', () => {
    let wrapper = mount(Form, {
      stubs: {
        transition: false
      },
      localVue,
      propsData: {
        initFormData: {
          name: '一塊兒團建',
          type: ['地推活動'],
          desc: '吃喝玩樂'
        }
      }
    })
    wrapper.find('.confirm').trigger('click')
    return Vue.nextTick().then(function() {
        expect(wrapper.vm.sucess).toBe(true)
        let url = 'http://rap2api.taobao.org/app/mock/233956/tbl-unit-test?name=' + wrapper.vm.ruleForm.name + '&nature=' + wrapper.vm.ruleForm.type.join(',') + '&form=' + wrapper.vm.ruleForm.form
        expect(axios.get).toBeCalledWith(url)
    })
  })
})

 

以上介紹了單元測試,以及如何在現有項目基礎上添加測試的配置,並寫了幾個測試用例,應該可讓不瞭解單元測試的同窗入門了,更高級點的能夠看 這裏 這個項目裏面的單元測試就比較全面,你們能夠參考下。

演示項目代碼: https://github.com/YalongYan/vue-test-utils-jest

參考鏈接:
Vue Test Utils
Jest Using With Wbpack
使用jest對vue項目進行單元測試
ui組件如何進行單元測試
Jest Mock
用Jest測試Vue中的Methods中的方法和Mock依賴

相關文章
相關標籤/搜索