vue中如何引入jest單元測試
一、前言
為什么要搞單元測試,好處有什么。
- 提測需要,代碼覆蓋率達到95%,分支覆蓋率達到100%,不達到要求,不給測。
- 確保代碼正確性。單元測試可以檢測和發(fā)現(xiàn)代碼中的錯誤,在開發(fā)期間及時糾正。
- 提高代碼質(zhì)量。進行單元測試可以思考更多場景,添加邊界測試用例,找到更多潛在的問題。通過反復(fù)測試和修改,代碼的質(zhì)量和可維護性得到提高。
- 方便重構(gòu)。如果代碼有充分的測試覆蓋率,重構(gòu)時就可以更加放心。當修改代碼時,運行測試用例可確保沒有破壞代碼的現(xiàn)有功能)。
- 加速開發(fā)流程。單元測試可以自動執(zhí)行,因此可以快速發(fā)現(xiàn)問題并且節(jié)省手動測試的時間,從而加速開發(fā)流程。
二、思想
在實際開發(fā)中想清楚vue組件的業(yè)務(wù)代碼和邏輯代碼的處理,把邏輯代碼抽離后編寫單元測試用例再針對業(yè)務(wù)代碼編寫組件測試用例。
單元測試
編寫單元測試是為了驗證小的、獨立的代碼單元是否按預(yù)期工作。一個單元測試通常覆蓋一個單個函數(shù)、類、組合式函數(shù)或模塊。單元測試側(cè)重于邏輯上的正確性,只關(guān)注應(yīng)用整體功能的一小部分。
組件測試
主要需要關(guān)心組件的公開接口而不是內(nèi)部實現(xiàn)細節(jié)。對于大部分的組件來說,公開接口包括觸發(fā)的事件、prop 和插槽。
當進行測試時,測試這個組件做了什么,而不是測試它是怎么做到的。
對于 視圖 的測試:根據(jù)輸入 prop 和插槽斷言渲染輸出是否正確。
對于 交互 的測試:斷言渲染的更新是否正確或觸發(fā)的事件是否正確地響應(yīng)了用戶輸入事件。
三、引入
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 = { // 預(yù)設(shè) preset: '@vue/cli-plugin-unit-jest', // // 多于一個測試文件運行時展示每個測試用例測試通過情況 verbose: true, // // 參數(shù)指定只要有一個測試用例沒有通過,就停止執(zhí)行后面的測試用例 bail: true, // // 測試環(huán)境,jsdom 可以在 Node 虛擬瀏覽器環(huán)境運行測試 testEnvironment: 'jsdom', // // 需要檢測的文件類型(不需要配置) moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], // // 預(yù)處理器配置,匹配的文件要經(jīng)過轉(zhuǎn)譯才能被識別,否則會報錯(不需要配置) // transform: { // // 用 `vue-jest` 處理 `*.vue` 文件 // // ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest", // // 用 `babel-jest` 處理 js // "^.+\\.js$": "babel-jest" // }, // // 轉(zhuǎn)譯時忽略 node_modules // transformIgnorePatterns: ['/node_modules/'], // // 從正則表達式到模塊名稱的映射,和webpack的alisa類似(不需要配置) // moduleNameMapper: { // '^@/(.*)$': '<rootDir>/src/$1' // }, // // Jest用于檢測測試的文件,可以用正則去匹配 testMatch: [ '**/tests/unit/**/*.spec.[jt]s?(x)', ], // // 是否顯示覆蓋率報告,開啟后顯示代碼覆蓋率詳細信息,將測試用例結(jié)果輸出到終端 collectCoverage: true, // // // 告訴 jest 哪些文件需要經(jīng)過單元測試測試 collectCoverageFrom: ["src/assets/js/*.{js,vue}"], // // // 覆蓋率報告輸出的目錄 coverageDirectory: 'tests/unit/coverage', // // // 報告的格式 // coverageReporters: ["html", "text-summary"], // // // 需要跳過覆蓋率信息收集的文件目錄 coveragePathIgnorePatterns: ['/node_modules/'], // // 設(shè)置單元測試覆蓋率閾值, 如果未達到閾值,Jest 將返回失敗 coverageThreshold: { global: { statements: 90, // 保證每個語句都執(zhí)行了 functions: 90, // 保證每個函數(shù)都調(diào)用了 branches: 90, // 保證每個 if 等分支代碼都執(zhí)行了 lines: 90 }, } }
注意事項:
(1)collectCoverageFrom 告訴Jest 哪些文件需要經(jīng)過單元測試測試;
(2)testMatch Jest用于檢測測試的文件,可以用正則去匹配;
(3)coverageThreshold 設(shè)置單元測試覆蓋率閾值, 如果未達到閾值,影響報告顏色(雖然你可以自己改)。
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-分支,F(xiàn)unction-函數(shù),Lines-代碼行數(shù)。
4. jest語法
4.1 匹配器(常用,剩下的可以看官網(wǎng))
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:數(shù)組用,檢測是否包含
- toHaveLength:數(shù)組用,檢測數(shù)組長度
4.2 Wrapper
- Wrapper:Wrapper 是一個包括了一個掛載組件或 vnode,以及測試該組件或 vnode 的方法
- Wrapper.vm:這是該 Vue 實例。你可以通過 wrapper.vm 訪問一個實例所有的方法和屬性
- Wrapper.classes:返回是否擁有該class的dom或者類名數(shù)組
- Wrapper.find:返回第一個滿足條件的dom
- Wrapper.findAll:返回所有滿足條件的dom
- Wrapper.html:返回html字符串
- Wrapper.text:返回內(nèi)容字符串
- Wrapper.setData:設(shè)置該組件的初始data數(shù)據(jù)
- Wrapper.setProps:設(shè)置該組件的初始props數(shù)據(jù)
- Wrapper.trigger:用來觸發(fā)事件
4.3 鉤子函數(shù)
- beforeAll 所有測試用例執(zhí)行之前執(zhí)行
- beforeEach 每個測試用例執(zhí)行之前執(zhí)行
- afterEach 每個測試用例執(zhí)行完之后執(zhí)行
- afterAll 所有測試用例執(zhí)行完之后執(zhí)行
使用場景,在測試接口api時,可以在beforeAll 先調(diào)登錄接口,獲取登錄信息執(zhí)行順序,如下圖所示。
五、問題
Q: 執(zhí)行 vue add @vue-cli-plugin-unit-jest 命令報錯,如下:
A: 把node版切到16以上即可。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-manage-system升級到vue3的開發(fā)總結(jié)分析
這篇文章主要為大家介紹了vue-manage-system升級到vue3的開發(fā)總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09Vue?3?表單與后端數(shù)據(jù)交互之查詢并回顯數(shù)據(jù)步驟流程
本文給大家介紹Vue3表單與后端數(shù)據(jù)交互之查詢并回顯數(shù)據(jù)步驟流程,結(jié)合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-12-12前端Vue設(shè)置cookie、刪除cookie,獲取cookie方式
這篇文章主要介紹了前端Vue設(shè)置cookie、刪除cookie,獲取cookie方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10Vue+axios使用FormData方式向后端發(fā)送數(shù)據(jù)
在前后端分離的項目中經(jīng)常使用到Vue+axios通過FormData的方式向后端發(fā)送表單數(shù)據(jù),下面就來介紹一下如何實現(xiàn),感興趣的可以了解一下2023-09-09vue使用路由守衛(wèi)實現(xiàn)菜單的權(quán)限設(shè)置
我們使?vue-element-admin前端框架開發(fā)后臺管理系統(tǒng)時,?般都會涉及到菜單的權(quán)限控制問題,下面這篇文章主要給大家介紹了關(guān)于vue使用路由守衛(wèi)實現(xiàn)菜單的權(quán)限設(shè)置的相關(guān)資料,需要的朋友可以參考下2023-06-06