Vue-Jest 自動(dòng)化測(cè)試基礎(chǔ)配置詳解
目前開發(fā)大型應(yīng)用,測(cè)試是一個(gè)非常重要的環(huán)節(jié),而在 Vue 項(xiàng)目中做單元測(cè)試可以用 Jest,Jest 是 facebook 推出的一款測(cè)試框架,集成了 Mocha, chai, jsdom, sinon 等功能,而且在 Vue 的腳手架中已經(jīng)集成了 Jest,所以在 Vue 項(xiàng)目中使用 Jest 做單元測(cè)試是不二的選擇,從提供的例子上看都很簡(jiǎn)單地配置并測(cè)試成功,然而在實(shí)際項(xiàng)目中有很多差異,我在測(cè)試自己的某個(gè)業(yè)務(wù)組件就報(bào)出很多錯(cuò)誤,本文就總結(jié)一下自己的踩坑經(jīng)歷,并幫助讀者快速解決配置中出現(xiàn)的問題。
安裝
可以通過官方提供的 @vue/cli 直接創(chuàng)建 Vue 項(xiàng)目,然后選中 Unit Testing 這個(gè)選項(xiàng)
? Check the features needed for your project: ◉ Choose Vue version ◉ Babel ❯◉ TypeScript ◯ Progressive Web App (PWA) Support ◉ Router ◉ Vuex ◯ CSS Pre-processors ◯ Linter / Formatter ◉ Unit Testing ◯ E2E Testing
然后在測(cè)試框架中選擇 Jest
? Pick a unit testing solution: Jest ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated con fig files
Vue + Ts 的項(xiàng)目最終生成的 jest.config.js 配置文件長(zhǎng)這樣,好像在告訴我們,我都給你們?cè)O(shè)置好了,直接用吧,然而針對(duì)項(xiàng)目,還需要手動(dòng)去配置兼容,要不然會(huì)報(bào)出很多錯(cuò)誤,無法進(jìn)行下去。
module.exports = {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel'
}
配置
先看看這個(gè)預(yù)設(shè)配置到底寫了什么,找到 @vue/cli-plugin-unit-jest/presets/typescript-and-babel 這個(gè)包,實(shí)際上這個(gè)輸出的配置如下:
module.exports = {
moduleFileExtensions: [ // 測(cè)試的文件類型
'js',
'jsx',
'json',
// tell Jest to handle *.vue files
'vue',
'ts',
'tsx'
],
transform: { // 轉(zhuǎn)化方式
// process *.vue files with vue-jest
'^.+\\.vue$': require.resolve('vue-jest'),
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
require.resolve('jest-transform-stub'),
'^.+\\.jsx?$': require.resolve('babel-jest'),
'^.+\\.tsx?$': require.resolve('ts-jest'),
},
transformIgnorePatterns: ['/node_modules/'], // 轉(zhuǎn)化時(shí)忽略 node_modules
// support the same @ -> src alias mapping in source code
moduleNameMapper: { // @符號(hào) 表示當(dāng)前項(xiàng)目下的src
'^@/(.*)$': '<rootDir>/src/$1'
},
testEnvironment: 'jest-environment-jsdom-fifteen',
// serializer for snapshots
snapshotSerializers: [ // 快照的配置
'jest-serializer-vue'
],
testMatch: [ // 默認(rèn)測(cè)試文件
'**/tests/unit/**/*.spec.[jt]s?(x)',
'**/__tests__/*.[jt]s?(x)'
],
// https://github.com/facebook/jest/issues/6766
testURL: 'http://localhost/',
watchPlugins: [
require.resolve('jest-watch-typeahead/filename'),
require.resolve('jest-watch-typeahead/testname')
],
globals: {
'ts-jest': {
babelConfig: true
}
}
}
其中比較重要的配置,也是我們比較多用來解決問題的配置:
- moduleFileExtensions : 測(cè)試的文件類型,這里默認(rèn)的配置基本涵蓋了文件類型,所以這里一般不需要改
- transform : 轉(zhuǎn)化方式,匹配的文件要經(jīng)過轉(zhuǎn)譯才能被識(shí)別,否則會(huì)報(bào)錯(cuò)。
- transformIgnorePatterns : 轉(zhuǎn)化忽略配置
- moduleNameMapper : 模塊別名,如果有用到都要填寫進(jìn)去
常見錯(cuò)誤
SyntaxError : 語(yǔ)法錯(cuò)誤,很可能是因?yàn)闆]有進(jìn)行轉(zhuǎn)化,比如下面的提示:
/Users/zhuangbing.cai/Documents/workspace/projects/wms-ui/node_modules/vue-runtime-helpers/dist/normalize-component.mjs:76
export default normalizeComponent;
^^^^^^
SyntaxError: Unexpected token 'export'
由于我們沒有對(duì) .mjs 文件進(jìn)行轉(zhuǎn)換導(dǎo)致了報(bào)錯(cuò),最快的解決方式就是在 transform 補(bǔ)充 .mjs 的轉(zhuǎn)化
transform: {
'^.+\\.mjs$': 'babel-jest'
}
只需要在對(duì) .mjs 的文件,提供轉(zhuǎn)化方式即可。
另一種語(yǔ)法錯(cuò)誤,是node_module 內(nèi)的某些文件需要轉(zhuǎn)化,然而被 transformIgnorePatterns 配置忽略了。
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/zhuangbing.cai/Documents/workspace/projects/wms-ui/node_modules/vue-runtime-helpers/dist/normalize-component.mjs:76
export default normalizeComponent;
^^^^^^
SyntaxError: Unexpected token 'export'
圖中 vue-runtime-helpers 被用到了,然而因?yàn)?transformIgnorePatterns 的配置忽略了轉(zhuǎn)化,從而導(dǎo)致語(yǔ)法錯(cuò)誤。解決方法就是改變 transformIgnorePatterns 的配置,如下:
transformIgnorePatterns: [
// 轉(zhuǎn)化時(shí)忽略 node_modules,但不包括 vue-runtime-helpers
'/node_modules/(?!(vue-runtime-helpers)/)',
],
將 vue-runtime-helpers 排除后,轉(zhuǎn)化的時(shí)候就不會(huì)忽略它,從而解決語(yǔ)法報(bào)錯(cuò)的問題。
Ts 類型錯(cuò)誤
TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
src/views/inventory-map/__tests__/available.spec.ts:15:1 - error TS2304: Cannot find name 'beforeEach'.
15 beforeEach(() => {
~~~~~~~~~~
src/views/inventory-map/__tests__/available.spec.ts:19:1 - error TS2593: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.
19 describe('available-inventory-map', () => {
~~~~~~~~
src/views/inventory-map/__tests__/available.spec.ts:20:3 - error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.
根據(jù)提示需要在 tscofig.json 中添加
{
"compilerOptions": {
"types": [
"webpack-env",
"jest"
],
}
}
測(cè)試前的工作
在編寫測(cè)試用例前,我們需要 Jest 提供組件實(shí)例 vm 和渲染的 DOM 結(jié)構(gòu)。對(duì)代碼邏輯、頁(yè)面效果的雙重測(cè)試保障,那么如何獲取到這個(gè)業(yè)務(wù)組件?
直接引用組件是不行的,因?yàn)槟愕臉I(yè)務(wù)組件需要的依賴很多,比如 UI 組件庫(kù)、工具函數(shù)、Vuex 的狀態(tài)等,所以首先我們需要處理好這些依賴。
處理依賴
首先要知道要測(cè)試的這個(gè)業(yè)務(wù)組件依賴了哪些東西,全局的依賴可以參照 main.ts 或 main.js 入口文件處,其他可根據(jù)組件中的引用來判斷。有了依賴后如何在 Jest 中獲得組件實(shí)例?
Vue 提供了一個(gè)單元測(cè)試實(shí)用工具庫(kù) - Vue Test Utils,編寫測(cè)試用例的時(shí)候可以用到它,首先利用 createLocalVue 創(chuàng)建一個(gè) Vue 的類供你添加組件、混入和安裝插件而不會(huì)污染全局的 Vue 類, 接著將依賴引用進(jìn)去。
const _localVue = createLocalVue();
_localVue.use(Vuex);
_localVue.use(UI);
_localVue.use(i18nInstall);
_localVue.component('s-filter', SFilter);
_localVue.component('w-table', WTable);
_localVue.directive('xxx', {
inserted: (el, binding) => {
....
},
});
export const localVue = _localVue;
這樣就拿到了一個(gè)包含依賴的 Vue 類,接著處理 Vuex,比如我們需要枚舉值
import enums from './enums';
export const systemStore = new Vuex.Store({
actions: {},
state: {
enums: {
systemEnums: enums,
},
},
});
生成實(shí)例和 DOM
在得到 localVue 和 store 之后,我們要用它去生成結(jié)果,通過 mount 將組件渲染出來。
import { localVue, systemStore } from '@/utils/unit-test/common';
import { mount } from '@vue/test-utils';
require('intersection-observer'); // 兼容jsdom不支持IntersectionObserver
import TaskList from '../available-inventory-map/index.vue'; // 引用要測(cè)試的業(yè)務(wù)
let store: any;
beforeEach(() => {
store = systemStore;
});
describe('available-inventory-map', () => {
it('篩選項(xiàng)測(cè)試', () => {
const renderer = createRenderer();
const wrapper = mount(TaskList, {
localVue,
store,
attachToDocument: true,
});
const html = wrapper.html(); // 得到完整的 html 結(jié)構(gòu)
const vm = wrapper.vm; // 組件實(shí)例
console.log(html, vm);
})
}
將 localVue 和 store,通過 mount 最終得到實(shí)例和它的 DOM 結(jié)構(gòu)。接下來就可以根據(jù)實(shí)例和 DOM 去編寫自己的測(cè)試用例啦。
總結(jié)
本文主要介紹了在 Vue + Ts 項(xiàng)目中配置 Jest 自動(dòng)化測(cè)試中遇到的問題總結(jié),介紹基本配置和常見錯(cuò)誤的解決方法,以及如何在開始編寫測(cè)試用例前得到完整的組件信息和 DOM。為接下來的用例編寫打下基礎(chǔ)。
引用
到此這篇關(guān)于Vue-Jest 自動(dòng)化測(cè)試基礎(chǔ)配置詳解的文章就介紹到這了,更多相關(guān)Vue-Jest 自動(dòng)化測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue 查看dist文件里的結(jié)構(gòu)(多種方式)
本文通過三種方式給大家介紹了vue 查看dist文件里的結(jié)構(gòu),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
vue打包terser壓縮去除控制臺(tái)打印和斷點(diǎn)過程
這篇文章主要介紹了vue打包terser壓縮去除控制臺(tái)打印和斷點(diǎn)過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
vue中監(jiān)聽input框獲取焦點(diǎn)及失去焦點(diǎn)的問題
這篇文章主要介紹了vue中監(jiān)聽input框獲取焦點(diǎn),失去焦點(diǎn)的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
vue與electron實(shí)現(xiàn)進(jìn)程間的通信詳情
這篇文章主要介紹了vue與electron實(shí)現(xiàn)進(jìn)程間的通信詳情,本文主要介紹electron渲染進(jìn)程和主進(jìn)程間的通信,以及在渲染進(jìn)程和主進(jìn)程中常用的配置項(xiàng),需要的朋友可以參考一下2022-09-09
vue實(shí)現(xiàn)下拉框篩選表格數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)下拉框篩選表格數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09

