單元測試(Jest 和 Mocha)

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

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

  • mocha-webpack 是一個 webpack + Mocha 的包裹器,同時包含了更順暢的接口和偵聽模式。這些設置能夠幫助咱們經過 webpack + vue-loader 獲得完整的單文件組件支持,但這自己是須要不少配置的。  node

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

 

用 Jest 測試單文件組件

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

  1. 經過一個 Jest 預編譯器npm

  2. 直接使用 webpack編程

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

  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對象用的是行爲驗證,並不須要寫太多的額外代碼。

相關文章
相關標籤/搜索