Vue3專案實踐jest,學會了升職加薪(上篇)

語言: CN / TW / HK

theme: vue-pro highlight: a11y-light


jest是什麼?

Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所需要的所有測試工具,是一款幾乎零配置的測試框架。它能支援很多框架,比如 Babel、TypeScript、Node、React、Angular、Vue 等諸多框架。

一、Vue3專案中安裝jest(文章中以vite、vue3專案為例)

1、使用 npm init vite 快速建立vue專案

js npm init vite 42a202ab4b90f300daf52ea2bac6f50.png

2、cd到專案中使用命令快速整合jest

vue中使用jest,其實並沒有我們想象的那麼複雜,之前我學習jest的時候,查了較多資料,也配置了許多設定,繁忙且繁瑣,直到最後我才發現,原來僅僅只需要執行一句指令即可。 js vue add @vue/cli-plugin-unit-jest

9f301ee30672fb89ac44a122c19579d.png

這個命令會幫我們把相關的配置都配好,相關的依賴都裝好,還會幫我們生成一個jest.config.js檔案。

3、jest中常用的一些配置項的介紹

js module.exports = { preset: "@vue/cli-plugin-unit-jest/presets/no-babel", // 預置外掛 moduleFileExtensions: [ //不需要配置 "js", "json", // 告訴 Jest 處理 `*.vue` 檔案 "vue", ], testMatch: [ //test檔案所在位置 "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)", ], transform: { // 用 `vue-jest` 處理 `*.vue` 檔案 "^.+\\.vue$": "vue-jest", // 用 `babel-jest` 處理 js "^.+\\.js$": "babel-jest", }, moduleNameMapper: { //不需要配置 "^@/(.*)$": "<rootDir>/src/$1", }, collectCoverage: true, //是否建立報告 collectCoverageFrom: ["**/*.{js,vue}", "!**/node_modules/**"], //建立報告的檔案來源 coverageReporters: ["html", "text-summary"], //報告的格式 coveragePathIgnorePatterns: [], //生成報告需要忽略的檔案,預設值為 node_modules globals: { //配置全域性變數,此處我配置了一個全域性變數VUE_APP_DATA,也可以在setup file中配置,如下說的lodash VUE_APP_DATA: { siteENV: "DEV" }, }, setupFiles: ["<rootDir>/src/jest-setup.js"], //啟動jest需要的檔案 };

4、在專案的根目錄中建立tests資料夾,再建立unit資料夾,在其中檔案命名以 xxx.spec.js命名(執行步驟2的時候,已經給我們預設建立)

5、在package.json中設定babel選項(重要)

js "babel": { "plugins": [ "@babel/plugin-transform-modules-commonjs" ] } 直接執行npm run test:unit,會出現錯誤提示 SyntaxError: Cannot use import statement outside a module,這是因為jest沒支援es6匯入匯出功能。

96e2a73ff95a7aa10d0046b22e653aa.png

6、在package.json 中新增啟動命令,然後通過在控制檯執行npm run test:unit 進行測試(執行步驟2的時候,已經給我們預設建立)

js npm run test:unit

二、jest的基本語法規則

1、jest 支援三種方式寫測試程式碼

  1. 以 .spec.js 命名
  2. 以 .test.js 命名
  3. 放在 __tests__資料夾下

2、測試程式碼結構

  • describe: 將幾個相關的測試放到一個組中,非必須
  • test:(別名it)測試用例,是測試的最小單位
  • expect:提供很多的matcher API來判定你的方法返回值是否符合特定條件

3、mock方法和前後處理

  • Jest的mock方式 (Jest.fn()、Jest.spyOn()、Jest.mock())
  • 預處理和後處理 beforeAll / afterAll  : 對測試檔案中所有的用例開始前/後進行統一的預處理 beforeEach/ afterEach :  在每個用例開始前/後進行預處理

4、覆蓋率指標

在package.json中 設定 --coverage 即可 測試覆蓋率 js "test:unit": "vue-cli-service test:unit --coverage"

665ac0b4b89e0d2e6a4ba4e0b57e23b.png

  • %Stmts是語句覆蓋率(statement coverage):是不是每個語句都執行了
  • %Branch分支覆蓋率(branch coverage):是不是每個if程式碼塊都執行了
  • %Funcs函式覆蓋率(function coverage):是不是每個函式都呼叫了
  • %Lines行覆蓋率(line coverage):是不是每一行都執行了

配置好並執行npm run test:unit之後,會生成一個coverage資料夾

7609b21a52a9c3cdbb49023ae74925c.png

然後開啟coverage/lcov-report裡面的index.html 裡面會有詳細的資訊展示

7bec68a96dd65334515ada84d3cc50a.png 柱狀條三種顏色分別代表不同比例的覆蓋率(<50%紅色,50% - 80%灰色, ≥80%綠色)

好的測試覆蓋率標準:80%以下不及格、90%以上可以使用、95%以上優秀

5、wrapper的宣告和用法

```js import { shallowMount } from '@vue/test-utils' import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => { it('renders props.msg when passed', () => { const msg = 'new message' const wrapper = shallowMount(HelloWorld, { props: { msg } }) expect(wrapper.text()).toMatch(msg) }) }) ``` mount: 建立一個包含被掛載和渲染的 Vue 元件的 wrapper,它僅僅掛載當前例項

shallowMount:和 mount 一樣,建立一個包含被掛載和渲染的 Vue 元件的 Wrapper,只掛載一個元件而不渲染其子元件 (即保留它們的存根),這個方法可以保證你關心的元件在渲染時沒有同時將其子元件渲染,避免了子元件可能帶來的副作用(比如Http請求等)。

shallowMount和mount的區別:在文件中描述為"不同的是被存根的子元件",就是說shallowMount不會載入子元件,不會被子元件的行為屬性影響該元件。

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:用來觸發事件

三、jest的常用API

  • toBe:匹配器有種類似於object.is或者===
  • toEqual:測試物件的內容是否相等,不比較物件的地址,只關心物件的內容是否一致,遞迴檢查物件或陣列的每個欄位
  • toBeNull:判斷是否為null
  • toBeUndefined:判斷是否為undefined
  • toBeDefined:與上相反
  • toBeNaN:判斷是否為NaN
  • toBeTruthy:判斷是否為true
  • toBeFalsy:判斷是否為false
  • toContain:陣列用,檢測是否包含
  • toHaveLength:陣列用,檢測陣列長度
  • toThrow:異常匹配

寫在最後

想了解更多jest實踐,歡迎瀏覽作者下一篇文章Vue3專案實戰jest,學會了升職加薪(下篇)

推薦兩個作者參與的開源專案,如果專案有幫助到你,歡迎star

一個簡單的基於Vue3、TS、Vite、qiankun技術棧的後臺管理專案:https://www.xkxk.tech

一個基於Vue3的仿Element plus元件專案:https://ui.xkxk.tech