結(jié)合現(xiàn)有項(xiàng)目,將使用到的前端框架(Vue橄务、Angular幔托、React)進(jìn)行單元測(cè)試配置,整理配置文檔
Vue
vue-cli在創(chuàng)建項(xiàng)目時(shí)可選擇單元測(cè)試框架(Mocha 或 Jest)仪糖,此處包含兩種測(cè)試框架配置
Vue & Mocha
項(xiàng)目創(chuàng)建
項(xiàng)目創(chuàng)建時(shí)選擇 Mocha 的Unit Testing
vue create vue-mocha
# 選擇手動(dòng)配置
? Please pick a preset:
zcloud (router, vuex, less, babel, eslint, unit-jest)
default (babel, eslint)
? Manually select features
? Please pick a preset: Manually select features
? Check the features needed for your project:
? Babel
? TypeScript
? Progressive Web App (PWA) Support
? Router
? Vuex
? CSS Pre-processors
? Linter / Formatter
? Unit Testing
?? E2E Testing
# 單元測(cè)試 mocha + chai
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with node-sass)
? Pick a linter / formatter config: Standard
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Pick a unit testing solution: (Use arrow keys)
? Mocha + Chai
Jest
添加測(cè)試報(bào)告mochawesome
現(xiàn)有架構(gòu)測(cè)試報(bào)告都是在命令行展示柑司,現(xiàn)在我們要將結(jié)果輸出并展示在頁(yè)面上
首先在項(xiàng)目中安裝 mochawesome:
npm install --save-dev mochawesome
然后在 package.json 中修改 test:unit 命令如下:
"test:unit": "vue-cli-service test:unit --reporter=mochawesome"
添加測(cè)試覆蓋率nyc
首先,在項(xiàng)目中安裝所需依賴(lài):
npm i --save-dev babel-plugin-istanbul istanbul-instrumenter-loader nyc
接著在項(xiàng)目根目錄下新建 nyc.config.js 文件锅劝,其內(nèi)容如下:
// 探索istanbul/nyc代碼覆蓋工具的原理 https://zhuanlan.zhihu.com/p/88524418
module.exports = {
'check-coverage': true,
'per-file': true,
'lines': 0,
'statements': 0,
'functions': 0,
'branches': 0,
'include': [
'src/**/*.js',
'src/**/*.vue'
],
'exclude': [
'src/abandon-ui/**',
'src/*.js',
'**/*.spec.js'
],
'reporter': [
'lcov',
'text',
'text-summary'
],
'extension': [
'.js',
'.vue'
],
'cache': true,
'all': true
}
完成后攒驰,在項(xiàng)目根目錄新建 vue.config.js, 其內(nèi)容如下:
const path = require('path')
const testMode = process.env.NODE_ENV === 'test'
module.exports = {
lintOnSave: false,
productionSourceMap: false,
chainWebpack: config => {
if (testMode) {
config.merge({
devtool: 'eval'
})
config.module
.rule('istanbul')
.test(/\.(js|vue)$/)
.include
.add(path.resolve(__dirname, '/src'))
.end()
.use('istanbul-instrumenter-loader')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
.before('babel-loader')
}
}
}
完成后,打開(kāi)項(xiàng)目根目錄下的 babel.config.js 文件故爵,修改如下:
const testMode = process.env.NODE_ENV === 'test'
module.exports = {
presets: ['@vue/cli-plugin-babel/preset']
presets: ['@vue/cli-plugin-babel/preset'],
plugins: testMode ? ['babel-plugin-istanbul'] : []
}
最后玻粪,打開(kāi) package.json 文件,修改 test:unit 命令:
"test:unit": "nyc vue-cli-service test:unit --reporter=mochawesome"
單元測(cè)試文件書(shū)寫(xiě)位置調(diào)整
如果我們的項(xiàng)目是一個(gè)去中心化的架構(gòu)诬垂,我們可能希望我們的單元測(cè)試文件位于我們的組件旁邊劲室,而不是都寫(xiě)在 tests/unit/ 目錄下。
在 tests/unit 目錄下新建 index.spec.js 文件结窘,其內(nèi)容如下:
// require all src files that ends with .spec.js
const srcContext = require.context('../../src/', true, /\.spec.js$/)
srcContext.keys().forEach(srcContext)
修改.eslintrc.js 配置
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)',
'**/src/**/*.spec.{j,t}s?(x)'
],
env: {
mocha: true
}
}
]
至此很洋,Vue+Mocha單元測(cè)試基本配置完成,執(zhí)行test:unit 命令后隧枫,可在項(xiàng)目中查看測(cè)試效果
Vue & jest
項(xiàng)目創(chuàng)建
項(xiàng)目創(chuàng)建時(shí)選擇 Jest 的Unit Testing喉磁,具體操作可查看Mocha的創(chuàng)建
添加測(cè)試報(bào)告
安裝依賴(lài):
npm i --save-dev jest-html-reporter
配置jest.config.js
jest集成了測(cè)試所需的功能谓苟,包括斷言,覆蓋率协怒,以及測(cè)試報(bào)告等涝焙,測(cè)試配置文件如下:
module.exports = {
preset: '@vue/cli-plugin-unit-jest',
moduleFileExtensions: [
'js',
// 告訴 Jest 處理 `*.vue` 文件
'vue'
],
moduleNameMapper: {
// 支持源代碼中相同的 `@` -> `src` 別名
'^@/(.*)$': '<rootDir>/src/$1'
},
transform: {
// 用 `babel-jest` 處理 `*.js` 文件
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
// 用 `vue-jest` 處理 `*.vue` 文件
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
},
testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)', '**/src/**/*.spec.{j,t}s?(x)'],
snapshotSerializers: [
// 快照的序列化工具
'<rootDir>/node_modules/jest-serializer-vue'
],
displayName: {
name: 'CLIENT',
color: 'blue'
},
// 成多種格式的測(cè)試覆蓋率報(bào)告 可選
collectCoverage: true,
collectCoverageFrom: ['**/*.{js,vue}', '!**/node_modules/**', '!**/dist/**', '!**/coverage/**'],
// report配置
reporters: [
'default',
[
'./node_modules/jest-html-reporter',
{
pageTitle: 'test report',
outputPath: 'testReport/JesttestReport.html',
includeFailureMsg: true
}
]
]
}
至此,Vue+Jest單元測(cè)試基本配置完成孕暇,執(zhí)行test:unit 命令后仑撞,可在項(xiàng)目中查看測(cè)試效果。
Jest相對(duì)Mocha而言妖滔,配置簡(jiǎn)單許多隧哮,開(kāi)箱即用,考慮到不同的庫(kù)需要學(xué)習(xí)不同的API铛楣,踩坑的風(fēng)險(xiǎn)也隨之提升近迁,后續(xù)框架均只采用Jest進(jìn)行配置。
Angular
Angular腳手架在創(chuàng)建項(xiàng)目時(shí)自動(dòng)配置單元測(cè)試簸州,采用Karma和Jasmine鉴竭,引入Jest需要遷移
angular & Jest
配置時(shí)默認(rèn)使用angular腳手架創(chuàng)建的項(xiàng)目
遷移
第一步,下載相關(guān)的依賴(lài)包:
npm i --save-dev jest jest-preset-angular @types/jest jest-html-reporter
第二步岸浑,在pakage.json中對(duì)Jest進(jìn)行配置搏存,也可直接配置jest.config.js
"jest": {
"preset": "jest-preset-angular",
"setupFilesAfterEnv": ["<rootDir>/src/setupJest.ts"]
}
第三步,在src目錄下創(chuàng)建上一步中設(shè)置的 setup 文件setupJest.ts
import 'jest-preset-angular'; // jest 對(duì)于 angular 的預(yù)配置
接下來(lái)矢洲,我們就可以在 package.json 的 script 中配置 test 的命令了:
"test": "jest"
此時(shí)璧眠,在命令行中運(yùn)行測(cè)試命令,就應(yīng)該能夠順利把測(cè)試跑起來(lái)并通過(guò)了读虏。如果沒(méi)有通過(guò)责静,可能是因?yàn)槲覀冊(cè)?code>src/tsconfig.spec.json中的 file 配置中有test.ts
的配置,這是 Karma 的 setup 文件盖桥,刪掉這行配置并刪除對(duì)應(yīng)的文件灾螃,(src/tsconfig.app.json
中出現(xiàn)的test.ts
也可一并刪除),重新執(zhí)行npm run test
即可
刪除 Karma 相關(guān)代碼
- 刪除相關(guān)依賴(lài)包(@types/jasmine @types/jasminewd2 jasmine-core jasmine-spec-reporter 因?yàn)樵?e2e 測(cè)試中有使用所以不能刪除):
npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
- 刪除文件
src/karma.config.js
- 刪除 angular.json中test的配置
-
src/tsconfig.spec.json
和compilerOptions.type
的配置移除 jasmine, 加上 jest揩徊。
至此腰鬼,Jest測(cè)試環(huán)境就算順利搭建好了
React
Create React App創(chuàng)建后react項(xiàng)目后,是默認(rèn)集成Jest的塑荒,所以我們只需完善配置即可
淺層渲染
如果你希望測(cè)試獨(dú)立于它們渲染的子組件的組件熄赡,我們建議使用 Enzyme
的 shallow() 渲染API。
第一步齿税,安裝enzyme依賴(lài)
npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer
第二步彼硫,修改src/setupTests.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
// 添加在測(cè)試中模擬的瀏覽器API
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
};
global.localStorage = localStorageMock;
覆蓋率報(bào)告
Jest 有一個(gè)集成的覆蓋率報(bào)告器,可以很好地與 ES6 配合使用,無(wú)需配置乌助。運(yùn)行 npm test -- --coverage