我的部落格:JavaScript單元測試框架
簡介
測試是保證程式碼質量的重要環節,web專案的單元測試雖然不能完全完成功能測試,但是卻能保證底層單一模組的工作質量,並且在程式碼重構的時候保證對外介面不會發生變化。
測試框架
- Mocha
- Jasmine
- Jest
- Tape
- Karma
Mocha
Mocha 是一個靈活的測試框架,但它只是一個結構,你需要引入其他外掛來實現一些測試功能,比如斷言庫、覆蓋統計等。
Mocha安裝
npm 安裝:npm install mocha --save-dev
指令碼語法
簡要示例:
// 引入需測試的模組或類
const add = require("./add");
const assert = require("assert");
// describe:定義一組測試
describe("加法函式測試", function() {
before(function() {
// runs before all tests in this block
});
// it: 定義一個測試用例
it("1 加 1 應該等於 2", function() {
// assert: nodejs內建斷言模組
assert.equal(add(1, 1), 2);
});
after(function() {
// runs after all test in this block
});
});
複製程式碼
使用方法
為測試指令碼建立目錄test-mocha
,測試指令碼命名應遵循[模組名].test.js
的風格,然後在package.json
中配置測試命令:
"scripts": {
"test-mocha": "mocha test-mocha/"
}
複製程式碼
執行npm run test-mocha
即可,將輸出測試結果如下圖:
斷言庫
Mocha 支援should.js
, chai
, expect.js
, better-assert
, unexpected
等斷言庫。以上一個示例,可以對比一下各個斷言庫的差別:
- assert
assert.ok(add(1, 1));
assert.equal(add(1, 1), 2);
複製程式碼
- should.js
(add(1, 1)).should.be.a.Number();
(add(1, 1)).should.equal(2);
複製程式碼
- expect.js
expect(add(1, 1)).to.be.a("number");
expect(add(1, 1)).to.equal(2);
複製程式碼
- chai:支援should, expect, assert三種語法
綜上,should.js
和expect.js
相較於assert
語義性更強,且支援型別檢測,而should.js
在語法上更加簡明,同時支援鏈式語法.and
。
hooks
Mocha 支援4種 hook,包括before / after / beforeEach / afterEach
。
非同步測試
Mocha 預設每個測試用例執行2000ms,超出時長則報錯,所以在測試程式碼中如果有非同步操作,則需要通過done
函式來明確測試用例結束。done
接受Error
引數。
BOM/DOM
Mocha 在node環境下執行時,不支援 BOM 和 DOM 介面,需要引入jsdom
和jsdom-global
庫。
Jasmine
Jasmine 是一個功能全面的測試框架,內建斷言expect
;但是有全域性宣告,且需要配置,相對來說使用更復雜、不夠靈活。
Jasmine安裝
npm 安裝:npm install jasmine --save-dev
指令碼語法
const add = require("../src/add");
describe("加法函式測試", function () {
it("1加1等於2", function() {
expect(add(1, 1)).toEqual(2);
});
it("輸出數字", function() {
expect(add(1, 1)).toEqual(jasmine.any(Number));
});
});
複製程式碼
Jasmine 的語法與 Mocha 非常相似,不過斷言採用內建的expect()
。
使用方法
新建配置檔案jasmine.json
:
{
// 測試指令碼相對路徑
"spec_dir": "test-jasmine",
// 測試指令碼
"spec_files": [
"*.test.js"
"!*.notest.js"
],
// 測試前需要引入的指令碼
"helpers": [],
// 是否在遇到第一個報錯後停止測試
"stopSpecOnExpectationFailure": false,
// 是否以半隨機順序執行測試
"random": false
}
複製程式碼
建立測試指令碼目錄test-jasmine
,指令碼檔案命名為[模組名].test.js
,在package.json
中配置測試命令:
"scripts": {
"test-jasmine": "jasmine --config=jasmine.json"
}
複製程式碼
然後執行npm run test-jasmine
即可,將輸出測試結果如下圖:
hook 和非同步
與 Mocha 相似。
Jest
Jest 是一個功能全面的“零配置”測試框架,既整合了各種工具,且無需配置即可使用。
Jest安裝
npm 安裝:npm install --save-dev jest
指令碼語法
Jest 語法與以上兩個框架不太相同:
const add = require("../src/add");
describe("加法函式測試", () => {
test("1加1等於2", () => {
expect(add(1, 1)).toBe(2);
});
});
複製程式碼
Jest 中以test
定義一個測試用例,且自帶斷言expect
,斷言庫功能強大,但語法相較於should.js
來說更復雜。
斷言語法:
- 普通匹配:
toBe
,not.toBe
- 空匹配:
toBeNull
,toBeUndefined
,toBeDefine
,toBeTruthy
,toBeFalsy
- 數字大小:
toBeGreaterThan
,toBeGreaterThanOrEqual
,toBeLessThan
,toEqual
,toBeCloseTo
(用於浮點數) - 正則匹配:
toMatch
- 陣列查詢:
toContain
- 構造匹配:
toEqual(expect.any(constructor))
使用方法
建立測試指令碼目錄test-jest
,指令碼檔案命名為[模組名].test.js
,在package.json
中配置測試命令:
"scripts": {
"test-jest": "jest test-jest/"
}
複製程式碼
然後執行npm run test-jest
即可,將輸出測試結果如下圖:
hook
Jest 同樣有四個hook,beforeAll/beforeEach/afterAll/afterEach
。
BOM/DOM
Jest 內建對 DOM 和 BOM 介面的支援。
覆蓋統計
Jest 內建覆蓋統計,為了更方便地進行相關配置,我們可以建立一個配置檔案jest.config.js
:
module.exports = {
// 開啟覆蓋統計功能
collectCoverage: true,
// 指定需要覆蓋的檔案
collectCoverageFrom: [
"src/*.js"
],
// 指定輸出覆蓋統計結果的目錄
coverageDirectory: "test-jest/coverage/",
// 指定測試指令碼
testMatch: [
"**/test-jest/*.test.js"
]
};
複製程式碼
然後將package.json
中的命名修改一下:"test-jest": "jest"
,再執行後可得如下結果: