在瀏覽器中使用 Mocha 和 Chai 進行單元測試
04 Sep 2017Mocha
Mocha 是一個 JavaScript 的測試框架,目的是用來管理測試程式碼,可在 Node.js 或瀏覽器環境運行。
在這裡指定介面(Interface)為 BDD。若使用 BDD 則提供 describe()
(同 context()
)、it()
(同 specify()
)、before()
、after()
、beforeEach()
與afterEach()
方法。以下對語法做簡單說明。
describe()
:圈出測試的區塊。例如,以下範例將以 function 為單位,因此 addClass 自己有一個測試的區塊,例如:describe('addClass', function() { /* ... */ });
。it()
: 設定個別 Test Case。例如,在以下的範例中,addClass 測試區塊內有兩個 Test Case - 「should add class into element」和「should not add a class which already exists in element」。before()
:在所有測試開始前會執行的程式碼區塊。after()
:在所有測試結束後會執行的程式碼區塊。beforeEach()
:在每個 Test Case 開始前執行的程式碼區塊。afterEach()
:在每個 Test Case 結束後執行的程式碼區塊。
語法範例。
describe('hooks', function() {
before(function() {
// run before all tests in this block
});
after(function() {
// run after all tests in this block
});
beforeEach(function() {
// run before each test in this block
});
afterEach(function() {
// run after each test in this block
});
// test case
it('should ...', function() {
// run test case
});
});
Chai
Chai 提供 BDD 語法測試用的斷言庫(Assertion Library)。斷言庫是一種判斷工具,明確地將預測結果指出。若實際結果和預測不同,就是測試有誤。以下對語法做簡單說明。
Assert
assert(expression, message)
:測試這個項目的 expression 是否為真,若為假則顯示錯誤訊息 message。
var assert = chai.assert;
describe('AssertTest', function() {
var foo = 'Hello';
var bar = 'World';
it('should be equal', function() {
assert('foo' === 'bar', 'foo is not bar');
});
});
Expect / Should
使用可串連的 getters 來完成斷言。這些可串聯的 getters 有 to、is、have 等。它很像英文,用很口語的方式做判斷。
var expect = chai.expect;
describe('ExpectTest', function() {
it('should be equal', function() {
expect(3).to.equal(2);
});
});
範例
完整程式碼在這裡。建立一個準備要測試的 function「addClass」,當對某個 element 加入 class 時,會檢查加入的 class 是否重覆,若沒有重覆就加進去
function addClass(el, newClass) {
if (el.className.indexOf(newClass) === -1) {
el.className += ' ' + newClass;
}
}
因此檢測的項目可條列為
- 是否成功加入新的 class
- 是否能檢測重覆加入 class
是否成功加入新的 class
加入一個新的 class,在這裡是加入 test-class,然後比對 element 的 class 是否擁有這個 class。在這裡的檢測方式是字串比對是否為「test-class」。
it('should add class into element', function() {
addClass(element, 'test-class');
assert.equal(element.className.trim(), 'test-class');
});
是否重覆加入 class
再次加入 test-class,因為前一次已經加過了,所以不可重覆加入。在這裡的檢測方式很簡單,由於是字串比對,因此只要看看字串是否是「test-class」,而非「test-class test-class」即可。
it('should not add a class which already exists in element', function() {
addClass(element, 'test-class');
assert.equal(element.className.trim(), 'test-class');
});
Hooks
在這裡也示範了before()
、after()
、beforeEach()
與afterEach()
的使用方式。
- 在所有 Test Case 執行前會先執行 before 的區塊,因此印出「before」。
- 在執行每一個 Test Case 前,會先執行 beforeEach 區塊,因此分別印出兩次「beforeEach」。
- 在執行每一個 Test Case 後,會去執行 afterEach 區塊,因此分別印出兩次「afterEach」。
- 在所有 Test Case 執行後會執行 after 的區塊,因此印出「after」。
檢測報告
推薦閱讀
- 從零開始: 測試吧! 前端 – 進擊的 Front End‘s – Medium:文筆幽默,帶大家手牽手實作第一個測試程式。