Vue CLI 擁有經過 Jest 或 Mocha 進行單元測試的內置選項。html
Jest 是功能最全的測試運行器。它所需的配置是最少的,默認安裝了 JSDOM,內置斷言且命令行的用戶體驗很是好。不過你須要一個可以將單文件組件導入到測試中的預處理器。咱們已經建立了 vue-jest 預處理器來處理最多見的單文件組件特性,但仍不是 vue-loader 100% 的功能。vue
mocha-webpack 是一個 webpack + Mocha 的包裹器,同時包含了更順暢的接口和偵聽模式。這些設置能夠幫助咱們經過 webpack + vue-loader 獲得完整的單文件組件支持,但這自己是須要不少配置的。 node
測試運行器就是運行測試的程序。webpack
Vue 的單文件組件在它們運行於 Node 或瀏覽器以前是須要預編譯的。咱們推薦兩種方式完成編譯:web
1. 經過一個 Jest 預編譯器npm
2. 直接使用 webpack編程
vue-jest 預處理器支持基本的單文件組件功能,可是目前還不能處理樣式塊和自定義塊,這些都只在 vue-loader 中支 持。若是你依賴這些功能或其它 webpack 特有的配置項,那麼你須要基於 webpack + vue-loader 進行設置。json
首先安裝 Jest 和 Vue Test Utils:數組
$ npm install --save-dev jest @vue/test-utils
而後在 package.json 中定義一個單元測試的腳本。瀏覽器
// package.json { "scripts": { "test": "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 來進行測試。
若是你在 webpack 中配置了別名解析,好比把 @ 設置爲 /src 的別名,那麼你也須要用 moduleNameMapper 選項爲 Jest 增長一個匹配配置:
{ // ... "jest": { // ... // 支持源代碼中相同的 `@` -> `src` 別名 "moduleNameMapper": { "^@/(.*)$": "<rootDir>/src/$1" } } }
安裝 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" } }]] } } }
Jest 推薦在被測試代碼的所在目錄下建立一個 tests 目錄,也能夠爲測試文件隨意設計本身習慣的文件結構。
Jest 能夠被用來生成多種格式的測試覆蓋率報告。
擴展你的 jest 配置 (一般在 package.json 或 jest.config.js 中) 的 collectCoverage 選項,而後添加 collectCoverageFrom 數組來定義須要收集測試覆蓋率信息的文件。
{ "jest": { // ... "collectCoverage": true, "collectCoverageFrom": ["**/*.{js,vue}", "!**/node_modules/**"] } }
這樣就會開啓默認格式的測試覆蓋率報告。能夠經過 coverageReporters 選項來定製它們。
{ "jest": { // ... "coverageReporters": ["html", "text-summary"] } }
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() }) })
經過 webpack 編譯全部的測試文件而後在測試運行器中運行。好處是支持 webpack 和 vue-loader 全部的功能。
首先要作的是安裝測試依賴:
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 會在任何測試以前運行,在該文件中設置測試所需的全局環境。
最後一個參數是該測試包所涵蓋的全部測試文件的聚合。
經過 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]' } }
Vue Test Utils 須要在瀏覽器環境中運行。能夠在 Node 中使用 jsdom-global 進行模擬:
npm install --save-dev jsdom jsdom-global
而後在 test/setup.js 中寫入:
require('jsdom-global')()
這行代碼會在 Node 中添加一個瀏覽器環境,這樣 Vue Test Utils 就能夠正確運行了。
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') }) })
在作單元測試的時候,要測試的方法須要引用不少外部依賴的對象,好比:(發送郵件,網絡通信,記錄Log, 文件系統之類的)。 而咱們無法控制這些外部依賴的對象。爲了解決這個問題,須要用到 Stub 和 Mock 來模擬這些外部依賴的對象,從而控制它們。
Stubs : 一般用於在測試中提供封裝好的響應,譬若有時候編程設定的並不會對全部的調用都進行響應。Stubs也會記錄下調用的記錄,它能夠用來記錄全部發送的信息或者它發送的信息的數目。(真實對象)
Mocks : 針對設定好的調用方法與須要響應的參數封裝出合適的對象。(模擬對象)
stub 使用的狀態驗證而 mock 使用的是行爲驗證