使用 Karma、Mocha、Chai 搭建支援 ES6 的測試環境

天方夜發表於2016-09-02

前端開發很多是介面開發,但我們可以將相對獨立的邏輯和功能從整體業務邏輯中獨立出來,這樣就可以對它們做單元測試。使用 Karma 可以比較方便地搭建出測試環境。

安裝 Karma

使用 Karma Mocha Chai(啟動器、測試框架、斷言庫)組合。

npm install karma karma-mocha karma-chai --save-dev

如果 npm 版本 >=3.0,會看到如下提示:

UNMET PEER DEPENDENCY chai@*
karma@1.2.0
karma-chai@0.1.0
karma-mocha@1.1.1
UNMET PEER DEPENDENCY mocha@*

這是因為 npm 已經不再自動安裝 peerDependencies:
We will also be changing the behavior of peerDependencies in npm@3. We won’t be automatically downloading the peer dependency anymore. Instead, we’ll warn you if the peer dependency isn’t already installed. This requires you to resolve peerDependency conflicts yourself, manually, but in the long run this should make it less likely that you’ll end up in a tricky spot with your packages’ dependencies.

於是繼續安裝 mocha chai

npm install mocha chai --save-dev

初始化 Karma

karma init

然後要回答一系列問題。

Which testing framework do you want to use ? Press tab to list possible options. Enter to move to the next question.
> mocha

Do you want to use Require.js ? This will add Require.js plugin. Press tab to list possible options. Enter to move to the next question.
> no

Do you want to capture any browsers automatically ? Press tab to list possible options. Enter empty string to move to the next question.
> Chrome

What is the location of your source and test files ? You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js". Enter empty string to move to the next question. > "test/**/*.spec.js" 01 09 2016 16:43:20.743:WARN [init]: There is no file matching this pattern.

>

Should any of the files included by the previous patterns be excluded ? You can use glob patterns, eg. "**/*.swp". Enter empty string to move to the next question.
>

Do you want Karma to watch all the files and run the tests on change ? Press tab to list possible options.
> yes

然後就可以看到 Karma 已經建立的配置檔案 karma.conf.js。如果選擇使用 PhantomJS,需要單獨安裝。

新增 ES6 支援

現在前端開發的原始碼一般使用了 ES6 甚至 ES7,將這個處理工作用 webpack 搞定。

npm install karma-webpack --save-dev

既然將 ES6 的處理交給 webpack,如果之前沒有安裝過 babel 環境,還需要安裝 babel-core babel-preset-es2015 以及 babel-loader

如果出現下面的 TypeError 錯誤,只要在 exclude 中加入 /node_modules/ 就好了。

TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

配置檔案 karma.conf.js 中,需要注意的還有 files preprocessors 以及 webpack 部分。

// Karma configuration
module.exports = function(config) {
  config.set({
    // ......

    files: [
      'test/**/*.spec.js'
    ],

    preprocessors: {
      'test/**/*.spec.js': ['webpack']
    },

    webpack: {
      resolve: {
        root: __dirname + "/src"
      },
      module: {
        loaders: [{
          test: /\.js$/,
          exclude: [/node_modules/, __dirname + "xxx/xxx/lib"],
          loader: "babel-loader",
          query: {
            compact: false,
            presets: ["es2015"],
            plugins: ["es6-promise"]
          }
        }]
      }
    },

    // ......
  })
}

啟動 Karma

編寫測試用例,這裡是一個使用斷言庫 Chai,並使用它的 expect 斷言風格的例子。

import {getMoneyText} from "xxx/xxx.js";
import {expect} from "chai";

describe("生成價格文案", () => {
  it("價格文案:積分", () => {
    expect(getMoneyText({
      payType: 1,
      price: 100,
      points: 100,
    })).to.be.equal("100積分");
  });

  it("價格文案:人民幣", () => {
    expect(getMoneyText({
      payType: 2,
      price: 100,
      points: 100,
    })).to.be.equal("¥100.00");
  });

  it("價格文案:人民幣+積分", () => {
    expect(getMoneyText({
      payType: 3,
      price: 100,
      points: 100,
    })).to.be.equal("¥100.00+100積分");
  });

  it("價格文案:人民幣+積分(多份數量)", () => {
    expect(getMoneyText({
      payType: 3,
      number: 5,
      price: 100,
      points: 100,
    })).to.be.equal("¥500.00+500積分");
  });
});

啟動 Karma

karma start

關於 Mocha (Chai, expect)的入門教程可以參考:測試框架 Mocha 例項教程

相關文章