JavaScript單元測試框架

多多洛愛學習發表於2019-03-20

我的部落格: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-執行指令碼

斷言庫

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.jsexpect.js相較於assert語義性更強,且支援型別檢測,而should.js在語法上更加簡明,同時支援鏈式語法.and

hooks

Mocha 支援4種 hook,包括before / after / beforeEach / afterEach

非同步測試

Mocha 預設每個測試用例執行2000ms,超出時長則報錯,所以在測試程式碼中如果有非同步操作,則需要通過done函式來明確測試用例結束。done接受Error引數。

BOM/DOM

Mocha 在node環境下執行時,不支援 BOM 和 DOM 介面,需要引入jsdomjsdom-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即可,將輸出測試結果如下圖:

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即可,將輸出測試結果如下圖:

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",再執行後可得如下結果:

jest覆蓋統計

相關文章