vue中如何引入jest單元測試
一、前言
為什么要搞單元測試,好處有什么。
- 提測需要,代碼覆蓋率達到95%,分支覆蓋率達到100%,不達到要求,不給測。
- 確保代碼正確性。單元測試可以檢測和發(fā)現代碼中的錯誤,在開發(fā)期間及時糾正。
- 提高代碼質量。進行單元測試可以思考更多場景,添加邊界測試用例,找到更多潛在的問題。通過反復測試和修改,代碼的質量和可維護性得到提高。
- 方便重構。如果代碼有充分的測試覆蓋率,重構時就可以更加放心。當修改代碼時,運行測試用例可確保沒有破壞代碼的現有功能)。
- 加速開發(fā)流程。單元測試可以自動執(zhí)行,因此可以快速發(fā)現問題并且節(jié)省手動測試的時間,從而加速開發(fā)流程。
二、思想
在實際開發(fā)中想清楚vue組件的業(yè)務代碼和邏輯代碼的處理,把邏輯代碼抽離后編寫單元測試用例再針對業(yè)務代碼編寫組件測試用例。
單元測試
編寫單元測試是為了驗證小的、獨立的代碼單元是否按預期工作。一個單元測試通常覆蓋一個單個函數、類、組合式函數或模塊。單元測試側重于邏輯上的正確性,只關注應用整體功能的一小部分。
組件測試
主要需要關心組件的公開接口而不是內部實現細節(jié)。對于大部分的組件來說,公開接口包括觸發(fā)的事件、prop 和插槽。
當進行測試時,測試這個組件做了什么,而不是測試它是怎么做到的。
對于 視圖 的測試:根據輸入 prop 和插槽斷言渲染輸出是否正確。
對于 交互 的測試:斷言渲染的更新是否正確或觸發(fā)的事件是否正確地響應了用戶輸入事件。
三、引入
1.新建vue項目直接用腳手架搭建項目時,勾選上單元測試即可。
2.舊項目添加單元測試,使用命令:vue add @vue-cli-plugin-unit-jest。
命令執(zhí)行成功后,根目錄下面多了tests文件夾和 jest.config.js 文件,tests文件夾下面有一個unit文件夾,里面包含了example.spec.js文件;
如下圖所示。

四、使用
1. jest.config文件
module.exports = {
// 預設
preset: '@vue/cli-plugin-unit-jest',
// // 多于一個測試文件運行時展示每個測試用例測試通過情況
verbose: true,
// // 參數指定只要有一個測試用例沒有通過,就停止執(zhí)行后面的測試用例
bail: true,
// // 測試環(huán)境,jsdom 可以在 Node 虛擬瀏覽器環(huán)境運行測試
testEnvironment: 'jsdom',
// // 需要檢測的文件類型(不需要配置)
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
// // 預處理器配置,匹配的文件要經過轉譯才能被識別,否則會報錯(不需要配置)
// transform: {
// // 用 `vue-jest` 處理 `*.vue` 文件
// // ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
// // 用 `babel-jest` 處理 js
// "^.+\\.js$": "babel-jest"
// },
// // 轉譯時忽略 node_modules
// transformIgnorePatterns: ['/node_modules/'],
// // 從正則表達式到模塊名稱的映射,和webpack的alisa類似(不需要配置)
// moduleNameMapper: {
// '^@/(.*)$': '<rootDir>/src/$1'
// },
// // Jest用于檢測測試的文件,可以用正則去匹配
testMatch: [
'**/tests/unit/**/*.spec.[jt]s?(x)',
],
// // 是否顯示覆蓋率報告,開啟后顯示代碼覆蓋率詳細信息,將測試用例結果輸出到終端
collectCoverage: true,
// // // 告訴 jest 哪些文件需要經過單元測試測試
collectCoverageFrom: ["src/assets/js/*.{js,vue}"],
// // // 覆蓋率報告輸出的目錄
coverageDirectory: 'tests/unit/coverage',
// // // 報告的格式
// coverageReporters: ["html", "text-summary"],
// // // 需要跳過覆蓋率信息收集的文件目錄
coveragePathIgnorePatterns: ['/node_modules/'],
// // 設置單元測試覆蓋率閾值, 如果未達到閾值,Jest 將返回失敗
coverageThreshold: {
global: {
statements: 90, // 保證每個語句都執(zhí)行了
functions: 90, // 保證每個函數都調用了
branches: 90, // 保證每個 if 等分支代碼都執(zhí)行了
lines: 90
},
}
}注意事項:
(1)collectCoverageFrom 告訴Jest 哪些文件需要經過單元測試測試;
(2)testMatch Jest用于檢測測試的文件,可以用正則去匹配;
(3)coverageThreshold 設置單元測試覆蓋率閾值, 如果未達到閾值,影響報告顏色(雖然你可以自己改)。
2. 測試用例
export default class Demo {
static TimeoutFn (cb) {
setTimeout(() => {
cb && cb("hello Timeout");
}, 1000)
}
static promiseFn () {
return new Promise(r => {
setTimeout(() => {
r("hello Promise");
}, 1000)
})
}
static TimeoutAsnycFn () {
return new Promise(r => {
setTimeout(() => {
r("hello asnyc");
}, 1000)
})
}
}demo
import Demo from "@/assets/js/demo.js";
describe("Demo File", () => {
it("TimeoutFn", done => {
let cb = t => {
expect(t).toBe("hello Timeout");
done();
}
Demo.TimeoutFn(cb);
})
it("promiseFn", () => {
return Demo.promiseFn().then(res => {
expect(res).toBe("hello Promise")
})
})
it("TimeoutAsnycFn", async () => {
let res = await Demo.TimeoutAsnycFn();
expect(res).toBe("hello asnyc");
})
})3. 報告輸出
- jest.config,js 文件中添加配置項 collectCoverage: true;
- package.json 命令行添加 “test:unit”: “vue-cli-service test:unit --coverage”,
- jest.config,js 文件刪除配置項 coverageReporters;(添加了終端不會顯示分支,代碼覆蓋統(tǒng)計情況)

4.報告路徑 /tests/unit/coverage/lcov-report/index.html;Statements-代碼,Branches-分支,Function-函數,Lines-代碼行數。

4. jest語法
4.1 匹配器(常用,剩下的可以看官網)
4.1.1 String,Number 類型用 toBe
test("add 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3)
})
test("add a + b to equal ab", () => {
expect("a" + "b").toBe("ab")
})4.1.2 Array,Object 類型用 toEqual
test('Array', () => {
expect(["a", "b"]).toEqual(["a", "b"]);
})
test('Object', () => {
expect({ name: 'xiaoming', age: 18 }).toEqual({ age: 18, name: 'xiaoming' });
})4.1.3 Boolean,Null, undefined
- toBeNull:判斷是否為null
- toBeUndefined:判斷是否為undefined
- toBeDefined:判斷是否不為undefined
- toBeNaN:判斷是否為NaN
- toBeTruthy:判斷是否為true
- toBeFalsy:判斷是否為false
4.1.4 其他
- toContain:數組用,檢測是否包含
- toHaveLength:數組用,檢測數組長度
4.2 Wrapper
- Wrapper:Wrapper 是一個包括了一個掛載組件或 vnode,以及測試該組件或 vnode 的方法
- Wrapper.vm:這是該 Vue 實例。你可以通過 wrapper.vm 訪問一個實例所有的方法和屬性
- Wrapper.classes:返回是否擁有該class的dom或者類名數組
- Wrapper.find:返回第一個滿足條件的dom
- Wrapper.findAll:返回所有滿足條件的dom
- Wrapper.html:返回html字符串
- Wrapper.text:返回內容字符串
- Wrapper.setData:設置該組件的初始data數據
- Wrapper.setProps:設置該組件的初始props數據
- Wrapper.trigger:用來觸發(fā)事件
4.3 鉤子函數
- beforeAll 所有測試用例執(zhí)行之前執(zhí)行
- beforeEach 每個測試用例執(zhí)行之前執(zhí)行
- afterEach 每個測試用例執(zhí)行完之后執(zhí)行
- afterAll 所有測試用例執(zhí)行完之后執(zhí)行
使用場景,在測試接口api時,可以在beforeAll 先調登錄接口,獲取登錄信息執(zhí)行順序,如下圖所示。

五、問題
Q: 執(zhí)行 vue add @vue-cli-plugin-unit-jest 命令報錯,如下:


A: 把node版切到16以上即可。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vue-manage-system升級到vue3的開發(fā)總結分析
這篇文章主要為大家介紹了vue-manage-system升級到vue3的開發(fā)總結分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
前端Vue設置cookie、刪除cookie,獲取cookie方式
這篇文章主要介紹了前端Vue設置cookie、刪除cookie,獲取cookie方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
Vue+axios使用FormData方式向后端發(fā)送數據
在前后端分離的項目中經常使用到Vue+axios通過FormData的方式向后端發(fā)送表單數據,下面就來介紹一下如何實現,感興趣的可以了解一下2023-09-09

