karma+mocha+webpack3 搭建 vue2 單元測試環境

這裏我記錄下搭建基於 karma+mocha+webpack3+vue2 的測試環境。由於以前折騰了一段時間,發現的坑挺深的,防止後面再次掉進坑裏,留個筆記。若是這邊文章能解決你們遇到的問題那就更好了?javascript

一、須要安裝哪些包

如下列出來的包安裝在項目中便可,還有幾個包須要全局安裝:
babel、mocha、karmacss

babel 相關的:html

  • babel-core
  • babel-plugin-syntax-jsx // 支持 jsx 語法
  • babel-plugin-transform-runtime // 描述太晦澀, 官方文檔: https://github.com/babel/babe...
  • babel-plugin-transform-vue-jsx // 支持 vue2.x jsx 語法
  • babel-preset-env // 能夠根據您所支持的環境自動肯定您須要的Babel插件和polyfills(.babelrc 配置)
  • babel-preset-es2015
  • babel-preset-stage-2
  • babel-runtime
  • babel-polyfill // 支持老版本瀏覽器

karma、mocha、斷言 包vue

  • karma
  • mocha
  • chai // BDD 、TDD 斷言框架
  • chalk // 終端裏能夠給輸出內容添加顏色
  • karma-mocha
  • karma-coverage // 生成代碼覆蓋率
  • karma-phantomjs-launcher // phantomjs 啓動器
  • karma-phantomjs-shim // 能夠支持 phantomjs 默認不支持的功能,如 Object.assign 等...
  • karma-sinon-chai
  • karma-spec-reporter // 終端裏輸出測試結果
  • karma-webpack // karma 支持 webpack 插件,有了它就不會報 找不到requirejs的錯誤信息了
  • phantomjs-prebuilt // phantomjs 經過 npm 安裝的版本
  • sinon // 測試輔助工具,提供 spy、stub、mock 三種測試手段,模擬特定場景
  • sinon-chai

webpack 相關java

  • webpack
  • babel-loader
  • css-loader
  • istanbul-instrumenter-loader // 代碼覆蓋率統計工具
  • karma-sourcemap-loader
  • style-loader
  • url-loader
  • vue-loader
  • vue-style-loader
  • extract-text-webpack-plugin

vue 核心包node

  • vue
  • vue-template-compiler
  • vue-router

二、如何配置

上面那麼一大坨包安裝好了,接下來該配置。配置主要是兩個,一是 karma 的配置文件,另外一個是 karma 須要的webpack 配置文件。webpack 的配置文件是爲了解析那些須要測試的源文件的,說白了就是 vue 相關的文件,而後再給karma 的單元測試用例去識別。webpack

webpack3 配置文件
我是手動建立一個webpack.test.config.js 文件,而後內容配置以下git

webpack 相關知識能夠參考我以前寫的一篇github

var path = require("path")
var webpack = require("webpack")
var ExtractTextPlugin = require('extract-text-webpack-plugin')

function resolve(dir) {

    return path.join(__dirname, '..', dir)
}

var webpackConfig = {

    module: {

        rules: [

            // babel-loader
            {
                test: /\.js$/,
                use: 'babel-loader',
                include: [resolve('src'), resolve('test')]
            },

            // 爲了統計代碼覆蓋率,對 js 文件加入 istanbul-instrumenter-loader
            {
                test: /\.(js)$/,
                exclude: /node_modules/,
                include: /src|packages/,
                enforce: 'post',
                use: [{
                    loader: "istanbul-instrumenter-loader",
                    options: {
                        esModules: true
                    },
                }]
            },

            // vue loader
            {
                test: /\.vue$/,
                use: [{
                    loader: 'vue-loader',
                    options: {
                        // 爲了統計代碼覆蓋率,對 vue 文件加入 istanbul-instrumenter-loader
                        preLoaders: {
                            js: 'istanbul-instrumenter-loader?esModules=true'
                        }
                    }
                }]
            },

            // css loader
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    use: 'css-loader',
                    fallback: 'vue-style-loader'
                })
            },

            // img loader
            {
                test: /\.(png|gif|jpe?g)(\?\S*)?$/,
                use: [{loader: 'url-loader'}]
            },

            // font loader
            {
                test: /\.(eot|woff|woff2|ttf|svg)(\?\S*)?$/,
                use: [{loader: 'url-loader'}]
            },
        ]
    },

    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            '@': resolve('src'), // 調用組件的時候方便點
        }
    },

    plugins: [
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        })
    ]
}

module.exports = webpackConfig

karma配置文件web

直接 cd 到你的項目,而後執行下面命令,會提示你是否使用 require.js、瀏覽器環境、測試腳本存放位置等等。

$ karma init

以後就會生成一個karma.config.js 文件,配置形式我是直接仿照vue-cli 官方的例子:

var webpackConfig = require('../../build/webpack.test.config');

module.exports = function (config) {
    config.set({
        // to run in additional browsers:
        // 1. install corresponding karma launcher
        //    http://karma-runner.github.io/0.13/config/browsers.html
        // 2. add it to the `browsers` array below.
        browsers: ['PhantomJS'],
        frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
        reporters: ['spec', 'coverage'],
        files: ['index.js'],
        preprocessors: {
            './index.js': ['webpack', 'sourcemap']
        },

        webpackMiddleware: {
            noInfo: true
        },
        // 不顯示 `webpack` 打包日誌信息
        webpackServer: {
            noInfo: true
        },
        webpack: webpackConfig,
        coverageReporter: {
            dir: './coverage',
            reporters: [
                { type: 'lcov', subdir: '.' },
                { type: 'text-summary' }
            ]
        }
    })
}

三、搭建目錄結構

├─build 
│      webpack.test.config.js
│
├─src 
│
├─package.json
│
└─test 
      └─unit
          │  index.js
          │  karma.config.js
          │
          ├─coverage
          │
          └─specs
               *.spec.js

測試文件相關都放置在 test/unit 下,入口文件爲 index.js,每一個vue 組件對應的測試用例名爲組件名稱.spec.js,根據 istanbul-instrumenter-loader 文檔的說明,測試總入口文件 index.js 內容以下:

import Vue from 'vue'

Vue.config.productionTip = false

// 測試全部以 .spec.js 名稱結尾的文件
// require all test files (files that ends with .spec.js)
const testsContext = require.context('./specs', true, /\.spec$/)
testsContext.keys().forEach(testsContext)

// 要求除main.js以外的全部src文件進行覆蓋
// require all src files except main.js for coverage.
// you can also change this to match only the subset of files that
// you want coverage for.
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
srcContext.keys().forEach(srcContext)

四、簡單的 vue 組件單元測試

咱們在 src 目錄下建立一個 Hello.vue 組件

<template>
   <div>msg</div>
</template>
<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

而後在 test/unit/specs 下建立一個 Hello.spec.js 文件,再寫個簡單的單元測試用例:

import Vue from 'vue'
import Hello from '@/components/Hello'

describe('Hello.vue', () => {
  it('should render correct contents', () => {
    const Constructor = Vue.extend(Hello)
    const vm = new Constructor().$mount()
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome to Your Vue.js App')
  })
})

五、測試輸出

在 package.json 中配置命令:

// package.json
 "scripts": {
    "test": "karma start test/unit/karma.config.js --single-run"
  }

輸出結果:
2

同時在 test/unit/coverage 生成測試報告。以上就是一個簡單的 vue 單元測試實例。最後奉上源代碼

首發於個人我的博客

相關文章
相關標籤/搜索