本例使用 karma、mocha、chai 為 webpack 項目添加單元測試。其中,karma 是測試過程管理架構,mocha 是運作測試用例的架構,chai 是單元測試斷言庫。下面一步步開始實踐吧:
1、項目目錄

- src:源代碼目錄
- test:測試用例目錄
- unit:測試檔案目錄
- cases.js:測試用例入口檔案
- karma.conf.js:karma 配置檔案
2、karma.conf.js
const path = require('path');
const ROOT_PATH = path.resolve(__dirname, '..');
const SRC_PATH = path.resolve(ROOT_PATH, 'src');
module.exports = (config) => {
config.set({
// Relative directory, files and exclude will based on it if it is set. The directory of karma.conf.js is the default value.
basePath: path.resolve(ROOT_PATH),
// Assert directory, directories can be used: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai'],
// Test reporter, reporters can be used: https://npmjs.org/browse/keyword/karma-reporter
// spec: Print each test case.
// progress: Print test progress.
// coverage-istanbul: Print code coverage.
reporters: ['spec', 'coverage-istanbul'],
// Files need be used when testing.
files: [
'test/cases.js' // Test entry file.
],
// Files need be preprocessed before testing, preprocressors can be used: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/cases.js': ['webpack']
},
// Files need be excluded when testing.
exclude: [],
// Config for webpack.
webpack: {
mode: 'development',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.js$/,
enforce: 'pre',
use: 'istanbul-instrumenter-loader', // Code coverage loader.
include: [SRC_PATH] // Directory of source files.
}
]
}
},
webpackMiddleware: {
noInfo: true
},
// Config for code coverage.
coverageIstanbulReporter: {
reports: ['html', 'lcovonly', 'text-summary'],
dir: path.resolve(ROOT_PATH, 'coverage'),
fixWebpackSourcePaths: true,
'report-config': {
html: {
subdir: 'html'
}
}
},
// Plugins used by karma when testing.
plugins: [
require('karma-chrome-launcher'), // Chrome launcher.
require('karma-mocha'), // mocha API is used in test cases.
require('karma-chai'), // chai API is used in test cases.
require('karma-webpack'), // Webpack API can be invoked by karma with karma-webpack.
require('karma-spec-reporter'), // Print test result.
require('karma-coverage-istanbul-reporter') // Print code coverage.
],
/**
* log level
* config.LOG_DISABLE // No info.
* config.LOG_ERROR // Print error info.
* config.LOG_WARN // Print warning info.
* config.LOG_INFO // Print all info.
* config.LOG_DEBUG // Print debug info.
*/
logLevel: config.LOG_ERROR,
// Browser used in testing, browsers can be used: IE, Chrome, ChromeCanary, FireFox, Opera, Safari, PhantomJS
browsers: ['Chrome'],
// Enable or disable continuous integration. When true is set, browser will be closed when finishing testing.
singleRun: true,
colors: true,
autoWatch: true,
// The numbers of browser to run cases in the same time.
concurrency: Infinity
});
};
- basePath:karma 配置 files 和 exclude 的基準目錄,預設值為 karma.conf.js 所在目錄
- frameworks:單元測試所用到的庫需要在此處引用
- reporters:單元測試結果輸出形式
- files:單元測試所需要依賴的檔案
- preprocessors:單元測試需要預處理的檔案。比如此處就需要用 webpack 預處理 cases.js
- exclude:需要排除的檔案
- webpack:webpack 配置項。此處需要用 coverage-istanbul 跑代碼覆寫率,是以此處添加了 loader istanbul-instrumenter-loader(由于代碼覆寫率需要提前在源碼中添加處理邏輯,是以跑代碼覆寫率此 loader 必須加)
- coverageIstanbulReporter:代碼覆寫率結果輸出配置項
- plugins:單元測試需要用到的插件。像測試架構、斷言庫、代碼覆寫率相關都需要在此處添加引用
- singleRun:是否禁用持續內建。如果設定為 true,所有測試用例完成後浏覽器會被自動關閉
- autoWatch:是否監聽檔案變更
3、package.json
"scripts": {
"unit": "karma start ./test/karma.conf.js"
},
在 scripts 中添加執行單元測試的指令,之後運作單元測試在指令行輸入 npm run unit 即可
4、測試用例
4.1 cases.js
cases.js 為測試用例入口檔案,入口檔案被添加在 karma.conf.js 的 files 項中。之後添加或删除測試檔案,直接操作 cases.js 即可,不用更改 karma.conf.js。
4.2 測試用例
var add = require('../../src/add');
describe('Test add', function () {
it('1 + 2 = 3', function () {
expect(add(1, 2)).equal(3);
});
});
檔案引用
- 這裡隻需要引用源檔案,在測試用例中調用源檔案方法進行測試即可
- 斷言庫不需要再引用,karma.conf.js 中已經有過聲明
測試 API
- describe 用來為測試用例分組
- it 為測試項。第一個參數為測試用例描述,第二個參數為測試用例回調函數
- expect、equal 為斷言 API