單元測試(Jest 和 Mocha)


 Vue CLI 擁有通過 Jest 或 Mocha 進行單元測試的內置選項。

  • Jest 是功能最全的測試運行器。它所需的配置是最少的,默認安裝了 JSDOM,內置斷言且命令行的用戶體驗非常好。不過你需要一個能夠將單文件組件導入到測試中的預處理器。我們已經創建了 vue-jest 預處理器來處理最常見的單文件組件特性,但仍不是 vue-loader 100% 的功能。

  • mocha-webpack 是一個 webpack + Mocha 的包裹器,同時包含了更順暢的接口和偵聽模式。這些設置可以幫助我們通過 webpack + vue-loader 得到完整的單文件組件支持,但這本身是需要很多配置的。  

  測試運行器就是運行測試的程序。

 

用 Jest 測試單文件組件

 Vue 的單文件組件在它們運行於 Node 或瀏覽器之前是需要預編譯的。我們推薦兩種方式完成編譯:

  1. 通過一個 Jest 預編譯器

  2. 直接使用 webpack

 vue-jest 預處理器支持基本的單文件組件功能,但是目前還不能處理樣式塊和自定義塊,這些都只在 vue-loader 中支 持。如果你依賴這些功能或其它 webpack 特有的配置項,那么你需要基於 webpack + vue-loader 進行設置。

  1. 安裝 Jest

  首先安裝 Jest 和 Vue Test Utils:

  $ npm install --save-dev jest @vue/test-utils

  然后在 package.json 中定義一個單元測試的腳本。

  // package.json
  {
    "scripts": {
      "test": "jest"
    }
  }

   2. 在 Jest 中處理單文件組件

     安裝和配置 vue-jest 預處理器(告訴 Jest 如何處理 *.vue 文件):

  npm install --save-dev vue-jest

  接下來在 package.json 中創建一個 jest 塊:

  {
    // ...
    "jest": {
      "moduleFileExtensions": [
        "js",
        "json",
        // 告訴 Jest 處理 `*.vue` 文件
        "vue"
      ],
      "transform": {
        // 用 `vue-jest` 處理 `*.vue` 文件
        ".*\\.(vue)$": "vue-jest"
      }
    }
  }

 注意:vue-jest 目前並不支持 vue-loader 所有的功能,比如自定義塊和樣式加載。還有,諸如代碼分隔等webpack 特有的功能也是不支持的。如果要使用這些不支持的特性,需要用 Mocha + webpack 來進行測試。

   3. 處理-webpack-別名

  如果你在 webpack 中配置了別名解析,比如把 @ 設置為 /src 的別名,那么你也需要用 moduleNameMapper 選項為 Jest 增加一個匹配配置:

  {
    // ...
    "jest": {
      // ...
      // 支持源代碼中相同的 `@` -> `src` 別名
      "moduleNameMapper": {
        "^@/(.*)$": "<rootDir>/src/$1"
      }
    }
  }

   4. 為 Jest 配置 Babel

  安裝 babel-jest(在測試中使用ES6特性):

  npm install --save-dev babel-jest

  接下來,在 package.json 的 jest.transform 里添加一個入口,來告訴 Jest 用 babel-jest處理 JavaScript 測試文件:

  {
    // ...
    "jest": {
      // ...
      "transform": {
        // ...
        // 用 `babel-jest` 處理 js
        "^.+\\.js$": "<rootDir>/node_modules/babel-jest"
      }
      // ...
    }
  }

  注意:默認情況下,babel-jest 會在其安裝完畢后自動進行配置。但也需要再次配置 babel-jest。

    • 開啟babel-preset-env,同時告訴 babel-preset-env 面向我們使用的 Node 版本。

    • 為了僅在測試時應用這些選項,把它們放到一個獨立的 env.test 配置項中 。

  .babelrc 文件示例:

  {
    "presets": [["env", { "modules": false }]],
    "env": {
      "test": {
        "presets": [["env", { "targets": { "node": "current" } }]]
      }
    }
  }

   5. 放置測試文件

  Jest 推薦在被測試代碼的所在目錄下創建一個 tests 目錄,也可以為測試文件隨意設計自己習慣的文件結構。

   6. 測試覆蓋率

  Jest 可以被用來生成多種格式的測試覆蓋率報告。

  擴展你的 jest 配置 (通常在 package.json 或 jest.config.js 中) 的 collectCoverage 選項,然后添加 collectCoverageFrom 數組來定義需要收集測試覆蓋率信息的文件。

  {
    "jest": {
      // ...
      "collectCoverage": true,
      "collectCoverageFrom": ["**/*.{js,vue}", "!**/node_modules/**"]
    }
  }

  這樣就會開啟默認格式的測試覆蓋率報告。可以通過 coverageReporters 選項來定制它們。

{
  "jest": {
    // ...
    "coverageReporters": ["html", "text-summary"]
  }
}

   7. 測試規范示例

  import { mount } from '@vue/test-utils'
  import Component from './component'
​
  describe('Component', () => {
    test('is a Vue instance', () => {
      const wrapper = mount(Component)
      expect(wrapper.isVueInstance()).toBeTruthy()
    })
  })

 

用 Mocha 和 webpack 測試單文件組件

  通過 webpack 編譯所有的測試文件然后在測試運行器中運行。好處是支持 webpack 和 vue-loader 所有的功能。

   1. 設置 mocha-webpack

  首先要做的是安裝測試依賴:

  npm install --save-dev @vue/test-utils mocha mocha-webpack

  接下來我們需要在 package.json 中定義一個測試腳本。

  // package.json
  {
    "scripts": {
      "test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
    }
  }
  • --webpack-config 標識指定了該測試使用的 webpack 配置文件。

  • --require 標識確保了文件 test/setup.js 會在任何測試之前運行,在該文件中設置測試所需的全局環境。

  • 最后一個參數是該測試包所涵蓋的所有測試文件的聚合。

   2. 提取 webpack 配置

   暴露 NPM 依賴

     通過 webpack-node-externals 外置所有的 NPM 依賴:

  // webpack.config.js
  const nodeExternals = require('webpack-node-externals')
​
  module.exports = {
    // ...
    externals: [nodeExternals()]
  }

  源碼表

    源碼表在 mocha-webpack 中需要通過內聯的方式獲取。推薦配置為:

  module.exports = {
    // ...
    devtool: 'inline-cheap-module-source-map'
  }

  IDE 中調試需要添加的配置:

  module.exports = {
    // ...
    output: {
      // ...
      // 在源碼表中使用絕對路徑 (對於在 IDE 中調試時很重要)
      devtoolModuleFilenameTemplate: '[absolute-resource-path]',
      devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
    }
  }

   3.設置瀏覽器環境

  Vue Test Utils 需要在瀏覽器環境中運行。可以在 Node 中使用 jsdom-global 進行模擬:

  npm install --save-dev jsdom jsdom-global

  然后在 test/setup.js 中寫入:

  require('jsdom-global')()

  這行代碼會在 Node 中添加一個瀏覽器環境,這樣 Vue Test Utils 就可以正確運行了。

   4. 選用一個斷言庫

  Chai 是一個流行的斷言庫,經常和 Mocha 配合使用。

  使用 expect 且令其全局可用,這樣我們就不需要在每個測試文件里導入它了:

  npm install --save-dev expect

  然后在 test/setup.js 中編寫:

  require('jsdom-global')()
​
  global.expect = require('expect')

  測試規范示例

  import { shallowMount } from '@vue/test-utils'
  import Counter from '../src/Counter.vue'
​
  describe('Counter.vue', () => {
    it('increments count when button is clicked', () => {
      const wrapper = shallowMount(Counter)
      wrapper.find('button').trigger('click')
      expect(wrapper.find('div').text()).toMatch('1')
    })
  })

 

Mock / Stub

  在做單元測試的時候,要測試的方法需要引用很多外部依賴的對象,比如:(發送郵件,網絡通訊,記錄Log, 文件系統之類的)。 而我們沒法控制這些外部依賴的對象。為了解決這個問題,需要用到 Stub 和 Mock 來模擬這些外部依賴的對象,從而控制它們。

  • Stubs : 通常用於在測試中提供封裝好的響應,譬如有時候編程設定的並不會對所有的調用都進行響應。Stubs也會記錄下調用的記錄,它可以用來記錄所有發送的信息或者它發送的信息的數目。(真實對象)

  • Mocks : 針對設定好的調用方法與需要響應的參數封裝出合適的對象。(模擬對象)

 stub 使用的狀態驗證而 mock 使用的是行為驗證。如果要基於stub編寫狀態驗證的方法,需要寫一些額外的代碼來進行驗證。而Mock對象用的是行為驗證,並不需要寫太多的額外代碼。


免責聲明!

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



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