vue 中的單元測試


一、背景

隨着項目越來越大,復雜度上升,改動一個地方,可能造成連環反應,引發未知 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')

以下待補充~~~~

state 測試

mutation 測試

action 測試

API 調用測試

mock 數據走完流程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM