vue2專案,踩坑Jest單元測試

daisy,gogogo發表於2022-03-02

目前的專案已經維護了挺久,由於客戶要求,我們要為專案加上單元測試,挑選一番後選擇了Jest(配置簡便,開箱即用),下面記錄了此次為專案新增Jest作為單元測試的經歷。

安裝Jest

1. 在專案目錄下,執行命令vue add @vue/cli-plugin-unit-jest,這個命令會幫我們把相關的配置都配好,相關的依賴都裝好,還會幫我們生成一個jest.config.js檔案,網上說還會生成tests資料夾,我試的沒有,另外還會幫你在eslintr.js檔案下配置好jest需要的配置。

   一開始的時候,我在編輯器下的控制檯輸這個命令,提示錯誤,後來改到系統下的控制檯才安裝成功。

用這個命令安裝是最方便的,我嘗試了幾次按照網上說的先安裝unit-jest,再安裝test-util之類的,都不成功。

 

2. 常用的一些jest配置項,在jest.config.js中配置。如果使用上面的命令,可以少配很多網上說的配置,比如下面標註了 不需要的

 

module.exports = {
    "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)$": "<rootDir>/node_modules/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需要的檔案
};

 

 

3. 如果第一步沒有自動生成tests資料夾,可以自己在專案目錄下建立tests資料夾,再建立units資料夾,並新增example.spec.js檔案,類似下面,具體原因可以看上面的配置項,testMatch,指定了test檔案在這個目錄下,這個可以自己配置

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

describe('HelloWorld.vue', () => {
  it('renders props.msg when passed', () => {
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      propsData: { msg }
    })
    expect(wrapper.text()).toMatch(msg)
  })
})

 

4. 在package.json中新增啟動命令,然後在控制檯執行 npm run test:unit ,可以看到測試結果

   "test:unit": "vue-cli-service test:unit"

 

Jest 踩坑

一開始的時候jes.config.js,其實沒有配置這麼多東西,有些配置是遇到問題後才加的,以下記錄的是遇到的問題,以及解決辦法

 

1.全域性變數報錯,可以配置globals(Object)屬性


2.webpack沒有打包進來的包,報錯,比如lodash,是以cnd形式引入的,專案中直接用_., 像這種需要配置setupFiles,把lodash新增給window物件,在src下的jest-setup.js檔案內加上如下程式碼,這個jest-setup.js就是jest測試需要的啟動檔案,上面有配置

import _ from 'lodash';
if (typeof window !== 'undefined') {
  window._ = _;
  window.VUE_APP_DATA.resource ={'app':'cfcf'}
}

 

3. canvas的api報錯,比如CanvasRenderingContext2D,需要安裝jest-canvas-mock,把他引入jest-setup.js檔案中

    import 'jest-canvas-mock';  

 

4.專案中引入第三方庫報錯,測試時Jest報錯,export default portalCommunication; ^^^^^^ SyntaxError: Unexpected token export > 1


   報錯原因是node_modules下的檔案預設是不會被transform的(預設配置),所以es6的寫法報錯了。

   解決辦法就是在transformIgnorePatterns中把需要transform的檔案排除掉,如下程式碼,node_modules的資料夾都不會被transform,除了element-ui/src/mixins,

   transformIgnorePatterns:["/node_modules/(?!(element-ui/src/mixins)/)"],

 

5.webpack指定 raw-loader!匯入的檔案,無法找到模組
需要將路徑對映新增到我的 jest 配置中,以便讓我的測試識別我設定的路徑對映
  "moduleNameMapper": {
      "!raw-loader!@/(.*)": "<rootDir>\\src/\\$1",

 

6. require.context is not a function 報錯,需要新增新的依賴, babel-plugin-transform-require-context

.babelrc中增加

env:{
 test:{
  plugins:["transform-require-context"] //修復3個jest test報錯
 }
}


7.
CDN引入的Element UI,Element元件提示沒有註冊,比如HelloWorld元件中使用到了 el-button元件,就會報錯是否
解決辦法就是在jest-setup.js中建立lcoalVue,localVue使用Element元件,這個localVue需要被引入測試檔案,測試元件的時候,使用這個localVue就可以了

import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld'
import {localVue} from '@/jest-setup'

describe('HelloWorld.vue', () => {

  it('renders component', () => {

    const wrapper = shallowMount(HelloWorld, {localVue})

    expect(wrapper.findAll('.hello-world').length).toBe(1)

  })

})

 

 

8.vue i18n國際化報錯:Vue warn]: Error in config.errorHandler: "TypeError: _vm.$t is not a function"

解決辦法就是,把某種國際化語言引入jest-setup.js,使用test-utils的mock api來mock全域性物件

參考這篇文章
https://www.cnblogs.com/jiemao/p/12777826.html

 

在這裡貼一下jest-setup.js檔案

import _ from 'lodash';
if (typeof window !== 'undefined') {
    window._ = _;
}

import 'jest-canvas-mock'; //修復2個報錯

import { config,createLocalVue } from '@vue/test-utils';
import ElementUI from 'element-ui';
import language from '@/i18n/en';
import $store from '@/store';

config.mocks={ //給test-utils設定全域性變數,適用於prototype定義的方法
    $t:(msg) => language[msg],
    $store:$store,
}

const testVue = createLocalVue();

testVue.use(ElementUI);

export const localVue = testVue;

 

如果文章對你有幫助,不妨給我個贊,謝謝~

相關文章