一、背景
隨着項目越來越大,復雜度上升,改動一個地方,可能造成連環反應,引發未知 bug
我們需要在保證項目穩定的情況下,進行開發
這里選擇 jest 作為測試框架
配置少,功能完善
二、安裝與配置
1、安裝 jest、@vue/test-utils
jest: 測試框架
@vue/test-utils: vue 測試工具,用來提供包裹 vue 組件,並暴露一些用來操作組件的方法和屬性
yarn add jest @vue/test-utils -D
2、在 package.json 中添加 script 命令
{
"script": {
"test": "jest" // 在 node 環境中運行 jest 命令
}
}
3、安裝 vue-jest 處理 vue 文件
yarn add vue-jest -D
添加 jest 配置文件 jest.config.js
// webpack 是支持 ES modules的,所以默認不開啟 ES modules 轉譯
// 這里要設置開啟 ES modules 轉譯,因為 node 環境不一定支持新特性
process.env.VUE_CLI_BABEL_TARGET_NODE = true
process.env.VUE_CLI_BABEL_TRANSPILE_MODULES = true
module.exports = {
// 告訴 jest 處理 js、jsx、json、vue 文件
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
// 告訴 jest 使用 vue-jest 處理 vue 文件
transform: {
'.*\\.(vue)$': 'vue-jest'
},
// jest 默認忽略對 node_modules 的轉換解析,我們項目中有使用到 vant 等包,所以不能忽略
// 這里隨便寫一個資源路徑進行覆蓋
transformIgnorePatterns: ['/src/assets'],
// 告訴 jest 關於 webpack 中的別名解析
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1' // 對應 @ ---> src
},
// snapshotSerializers: ['jest-serializer-vue'],
// 啟動測試命令時,自動尋找匹配文件執行
testMatch: [
'**/test/**/*.test.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
]
// testURL: 'http://localhost/',
// watchPlugins: [
// 'jest-watch-typeahead/filename',
// 'jest-watch-typeahead/testname'
// ]
}
4、安裝 babel-jest
測試代碼可能使用了很多新的語法特性
因為是跑在 node 環境中,node 可能並不支持
所以要使用 babel-jest 在運行代碼前來進行轉換
yarn add babel-jest -D
在 jest.config.js 中 transform 屬性添加配置
module.exports = {
// 告訴 jest 使用 babel-jest 處理 js 文件
transform: {
'^.+\\.js$': 'babel-jest'
}
}
5、安裝 jest-transform-stub
解析到靜態資源如圖片、樣式表時使用 jest-transform-stub 處理
jest-transform-stub 實際是返回一個空字符串,因為測試時並不需要這些資源
yarn add jest-transform-stub -D
在 jest.config.js 中 transform 屬性添加配置
module.exports = {
// 告訴 jest 使用 jest-transform-stub 處理靜態資源
transform: {
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub'
}
}
6、放置測試文件
默認情況下 jest 會遞歸查找整個項目中所有的 .spec.js 和 .test.js 擴展名的文件
推薦在測試目錄下創建一個 __test__
目錄,放置測試文件
7、eslintrc.js
在 env 中加入 jest,讓 eslint 識別 jest 全局變量
{
env: {
jest: true
}
}
三、使用
思考測試邏輯
// 一開始不知道要測試什么,怎么測試
// 我們可以把需要測試的情況羅列出來,然后一一編碼,先思考后動手
// 1、issuerName 1、截取18個字符 2、沒有值時為'--'
// 2、h2Style 1、發行人+標簽長度如果大於22,則改變字體大小
// 3、limitTags 1、最多截取三個標簽 2、沒有值時為[]
// 4、buyYtm 1、精確到小數后3位 2、沒有值時為'--'
// 5、paymentFrequency 1、有值時后續加上'付息' 2、沒有值時位'--'
// 6、paymentDates 1、付息日超過2個(不包含)則在后面加上'等',並且只截取前兩個展示 2、沒有值時為'--'
取值對比方式
// Q:直接使用 wrapper.vm 獲取數據進行對比還是取頁面上展示的文本進行對比?
// A:我比較傾向於第二種,取頁面上展示的文本進行對比
// 組件中可能因為各種原因,不敢修改之前的變量數據。
// 此時新增變量替換原先模板中的變量,頁面上展示改變了,但是腳本中原有變量還在,測試正常通過,這是不對的
// 所以應該以實際頁面展示為准。
// 只有在頁面上無法測試到的時候,直接拿 wrapper.vm 上的數據對比
方法
1、構造輸入值
2、傳入`構造輸入值`給要測試的方法, 並執行
3、對比測試執行方法`返回的結果/產生的影響`與預期的是否一樣
util 測試
如果引入了依賴包,jest 找不到,需要在 jest.config.js 中的 moduleNameMapper 配置依賴包的解析路徑
moduleNameMapper: {
'^dayjs$': '<rootDir>/node_modules/dayjs'
}
window.location.href 需要在 jest.config.js 中的
testURL: 'http://www.baidu.com?test1=123&test2=321'
自定義日期對象方法,可以測試倒計時類似的方法
let t1 = new Date('2020-05-15').getTime()
let t2 = new Date('2022-05-15').getTime()
let initTime = new Date('2019-10-18').getTime()
Date.prototype.getTime = function() {
return initTime
}
props 測試
const wrapper = mount(component, {
propsData: {
}
})
wrapper.props()
wrapper.props('key')
以下待補充~~~~