Vue 項目添加單元測試發現的問題及解決


用 Jest 測試單文件組件

1、安裝 Jest 和 Vue Test Utils

npm install --save-dev jest @vue/test-utils

2、配置 package.json

// package.json
{
  "scripts": {
    "test": "jest"
  }
}

3、需要安裝和配置 vue-jest 預處理器

npm install --save-dev vue-jest

4、在package.json 中創建一個 jest 塊或在項目根目錄創建 jest.config.js

module.exports = {
  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
      'jest-transform-stub',
     // 為 Jest 配置 Babel
    '^.+\\.jsx?$': 'babel-jest'
  },
  transformIgnorePatterns: ['/node_modules/'],
  // 別名
  moduleNameMapper: {
    '^@/(.*)$': '<rootdir>/src/$1'
  },
  snapshotSerializers: ['jest-serializer-vue'],
  testMatch: [
    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
  ],
  testURL: 'http://localhost/',
  watchPlugins: [
    'jest-watch-typeahead/filename',
    'jest-watch-typeahead/testname'
  ]
};

錯誤信息處理

1、babel 解析 es6 出錯,需要配置 babel 預設


> 需要配置安裝 @babel/preset-env [babel-preset-env 會有問題]

npm install --save-dev @babel/preset-env

> 配置 babel.config.js

module.exports = {
  presets: [
    // 使可以正常運行 vue 項目,
    '@vue/app',
    [
      '@babel/preset-env',
      {
        modules: false,
      }
    ]
  ],
  env: {
    test: {
      presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
    }
  }
}

2、npm test

> 清除緩存,然后再執行測試參考鏈接

最后問題還是很多,比如 UI 包的引用,webpack require.context 的問題等

然后就決定重新創建一個項目,看看有沒有問題(想着官網的例子不應該是有問題的)

1、創建項目

vue create jest-demo

2、選擇插件包(前一個項目大致的插件【vue-router, vuex, dart-sass, babel, eslint, unit-jest】)安裝

vue-router, vuex, dart-sass, babel, eslint, unit-jest

3、寫一個簡單的組件('@/components/HelloWorld.vue')用做測試,簡單含有一些之前項目會遇到的情況(store【如 mapGetter】、element-ui標簽)

<template>
  <div class="hello">
    <div>{{msg}}</div>
    <el-row type="flex" align="middle">
      <el-col :span="4">userName</el-col>
      <el-col :span="8"><el-input v-model="moduleUserName"></el-input></el-col>
    </el-row>
    <el-button type="primary" @click="changeUser">change user</el-button>
  </div>
</template>

<script>
import { mapGetters, mapMutations } from 'vuex'
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
  },
  data() {
    return {
    }
  },
  computed: {
    ...mapGetters(['storeUserName']),
    moduleUserName: {
      set(name) {
        this.updateUserName(name)
      },
      get() {
        return this.storeUserName
      }
    }
  },
  methods: {
    ...mapMutations(['updateUserName']),
    changeUser() {

    },
  }
};
</script>

4、寫一個對應的測試文件

import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'
import ElementUI from 'element-ui';
import HelloWorld from '@/components/HelloWorld.vue';
import store from '@/store'

describe('HelloWorld.vue', () =&gt; {
  it('renders props.msg when passed', () =&gt; {
    const localVue = createLocalVue()
    localVue.use(Vuex)
    localVue.use(ElementUI)
    const msg = 'new message';
    const wrapper = shallowMount(HelloWorld, {
      // 做一個數據的傳
      propsData: { msg },
      // 使用 store
      store,
      // 避免混入和安裝插件而污染全局 Vue
      localVue,
    });
    expect(wrapper.text()).toMatch(msg);
  });
});


OK 沒有問題了,把包的配置和各文件的配置寫入老再試試


5、原項目中有自動引入固定前綴的組件的插件,需要用到 webpack 的 require.context 函數對文件做檢索,然后 babel-jest 是沒有的,所以需要引用一個三方的插件來提供這個功能

  • 安裝 babel-plugin-require-context-hook
cnpm install babel-plugin-require-context-hook 
  • 在測試文件夾內創建文件 tests/unit/lib/register-context.js
import registerRequireContextHook from 'babel-plugin-require-context-hook/register';
registerRequireContextHook();
  • 在 jest.config.js 中配置 jest 預配置,使可以使用 require.context
setupFiles: ['<rootdir>/tests/unit/lib/register-context.js']
  • 在 babel.config.js 中配置 test 環境插件 require-context-hook
env: {
    test: {
        plugins: ['require-context-hook']
    }
}

6、其他的一些設置

  • 因為項目中有引用 element-ui 和 vue-awesome,需要被 babel 解析,排除掉這兩個包,在 jest.config.js 中配置
transformIgnorePatterns: [
    'node_modules/(?!(element-ui|vue-awesome)/)'
 ],
  • 因為很多測試組件的時候需要引入很多文件或包,所以就提出來 js 文件,類似 vue 的 main.js ,做入口的統一處理,
  • 創建 tests/unit/lib/before-test.js 【基本的都是在 main.js 中引入的或添加】
// 為了方便 單元測試
// eslint-disable-next-line import/extensions
import element from '@/plugins/element'
import baseComponent from '@/plugins/base-component'
import registeSvgIcon from '@/plugins/registe-svg-icon'
import API from '@/request/api'
import axios from '@/request'
import utils from '@/utils'
jest.mock('axios')
export default (Vue) =&gt; {
  element(Vue)
  baseComponent(Vue)
  registeSvgIcon(Vue)
  Vue.prototype.$API = API
  Vue.prototype.axios = axios
  Vue.prototype.$util = utils
}

  • 創建 Hello.vue 組件【@/views/pages/Hello】
<template>
  <div class="hello">hello</div>
</template>

<script>
export default {
  name: 'hello',
  created() {
    console.log('hello')
  }
}
</script>

<style lang="scss" scoped="">
.hello {}
</style>

  • 創建測試文件 tests/unit/hello.spec.js
import { shallowMount, createLocalVue } from '@vue/test-utils'
import './lib/before-test'
import Hello from '@/views/pages/Hello'

describe('我是外層分組', () =&gt; {
  const localVue = createLocalVue()
  const wrapper = shallowMount(Hello, { localVue })
  it('wrapper 是一個 vue 組件實例', () =&gt; {
    expect(wrapper.isVueInstance()).toBeTruthy()
  })
})


7、然后就可以學習 jest ,並用 jest 具體的添加單元測試了【雖然沒有按問題來解決,但是項目添加單元測試總算OK了,先學習jest吧,再遇到問題再解決問題,結果是好的就好了~~】


  • 其他的一些問題

    原因:jsdom不支持canvas,需要額外引入包
    解決:安裝jest-canvas-mock包,在jest的配置文件中添加 setupFiles: ['jest-canvas-mock']

 


免責聲明!

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



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