一、測試框架
1、Mocha
簡介
相對比較新,運行在node.js上的JavaScript測試框架,可以用來做 TDD(Test-Driven Development)或 BDD(Behavior Driven Development)風格的測試。
說明:
TDD:測試驅動開發,解決的是代碼級的驗證,但是測試代碼與需求的符合問題解決得不是很好,非技術人員、客戶看不懂代碼,無法評審測試是否符合需求。
BDD:行為驅動開發,理念是使用自然語言來描述功能,而且強調的是使用例子來說明需求功能。
特性
(1)全局變量泄露測試
Mocha 能夠發現那種不小心創建出來的全局變量泄露,如果創建了全局變量,它會在測試時拋出錯誤。如果想禁用全局泄露檢查,可以運行 mocha 命令時加上 --ignored-leaks 選項。
(2)用 Mocha掛鈎定義設置和清理邏輯
BDD 接口 beforeEach()、afterEach()、before()和 after()接受回調,可以用來定義設置和清理邏輯。
(3)測試異步邏輯
給定義測試邏輯函數添加一個參數,就可以把 Mocha 測試用例定義為異步的。這個參數通常被命名為done
。
安裝
npm install mocha
示例
describe('---------- XX管理 ----------', function () { describe('< 新增XX >', function () { it('當條件齊全時插入成功', function (done) { request.post('/XX') .set('Content-Type', 'application/json') .set('Cookie', cookie) .send({ "data": '[{' + ' "VehicleId":"1000100",' + ' "VehicleType":"面包車"' + '}]' }) .expect(200, function (err, res) { should.not.exist(err); res.text.should.containEql('"result":1'); done(); }); }); }); });
說明:
describe
塊:被稱為測試套件,表示一組相關的測試,它是一個函數,第一個參數是測試套件的名稱,第二個參數是一個實際執行的函數。
it
塊:被稱為測試用例,表示一個單獨的測試,是測試的最小單位,也是一個函數,第一個參數是測試用例的名字,第二個參數是一個實際執行的函數。
所有的測試用例(it塊)都應該含有一句或多句斷言,是編寫測試用例的關鍵,Mocha本身不包含斷言,斷言是由斷言庫來實現的,因此需要先引入斷言庫。
運行測試代碼
mocha默認運行test子目錄里面的測試腳本,一般情況下,可以把測試腳本放在test目錄下,然后進入項目對應的目錄,直接執行mocha命令即可。
上面的命令只會執行test第一層目錄下所有文件,並不能執行嵌套目錄下的文件。為了執行所有嵌套目錄下的文件,使用 mocha --recursive 。
執行test目錄中的單個測試文件,使用mocha test/XXX.test.js
制作網頁版報告
全局安裝:
npm install -g --save-dev mochawesome
執行命令:
mocha --reporter mochawesome
說明:
1、使用上面的命令生成的報告中包含test目錄下所有測試文件,若對某個測試文件生成報告在命令后加XXX.js 。
2、本地安裝與全局安裝
本地安裝
- 將安裝包放在 ./node_modules 下(運行 npm 命令時所在的目錄),如果沒有 node_modules 目錄,會在當前執行 npm 命令的目錄下生成 node_modules 目錄。
- 可以通過 require() 來引入本地安裝的包。
全局安裝
- 將安裝包放在 /usr/local 下或者你 node 的安裝目錄。
- 可以直接在命令行里使用。
2、Vows
簡介
在Vows 下寫的測試代碼結構更加強,Vows想讓測試更容易理解和維護。
按Vows 的定義,一個測試套件中包含一個或多個批次。可以把批次當做是一組相互關聯的情境,或者要測試的概念領域。批次和上下文是並行運行的。上下文中可能包含主題、一個或多個誓約,以及/或者一或多個先關聯的情境(內部情況也是並行運行的)。主題是跟情境相關的測試邏輯。誓約是對主題結果的測試。
套件---批次---情境 -----主題
|----誓約
|----情境
安裝
npm install -g vows
示例
const vows = require('vows'); const assert = require('assert'); const Todo = require('../todo'); // 批次 vows.describe('Todo').addBatch({ // 情景 'when adding an item': { // 主題 topic: () => { const todo = new Todo(); todo.add('Feed my cat'); return todo; }, // 誓約 'it should exist in my todos': (er, todo) => { assert.equal(todo.length, 1); } } }).export(module);
二、斷言庫
1、assert
簡介
assert模塊是Node中大多數單元測試的基礎,很多第三方測試框架都用到了assert模塊,甚至沒有測試框架也可以用它做測試。
常用斷言
(1)equal:檢查變量的值。
示例:
assert.equal(todo.length, 1, '1 item should exist');
(2)notEqual:找出邏輯問題。
示例:
assert.notEqual(todo.length, 0, '1 item should exist');
(3)ok:判斷值是否為true。
示例:
assert.ok (value, 'Callback should be passed true');
說明:
除了 equal 和 notEqual ,assert 模塊還提供了更嚴格的版本,strictEqual 和 notStrictEqual,它們在進行判斷時用的是嚴格的相等操作符 ===。
assert 模塊也有用來比較對象的 deepEqual 和 notEqual ,這些斷言中的 deep 表明它們會層層深入對兩個對象進行比較,比較兩個對象的屬性,如果屬性也是對象,則會繼續比較屬性的屬性。
不足:使用assert模塊時,每個測試用例中都要包含很多套路化的代碼用於設置測試、追蹤測試進程,會占用一些時間和精力。
2、should.js
簡介
是富有表現力、可讀、框架無關的斷言庫。Should.js 跟其他框架的搭配很容易,因為它只是給 Object.prototype 增加了一個 should屬性。這樣你就可以寫出表達能力更強的斷言。
比如 user.role.should.equal('admin')或者users.should.include('rick')
安裝
npm install should
常用斷言
.exactly:全等,相當於===
示例:
(5).should.be.exactly(5)
.ok: 對象存在
示例:
true.should.be.ok; false.should.not.be.ok;
.true:真
示例:
(5===5).should.be.true
.eql:相等,相當於 ==
示例:
[1,2,3].should.eql([1,2,3]);
[1, 2, 3].should.eql({ '0': 1, '1': 2, '2': 3 });
說明:上面第二個例子,它們是不同的類型,但實際內容相同,這樣也是正確的。
.NaN:非數字
示例:
(undefined + 0).should.be.NaN;
.typeof:判斷類型
示例:
'test'.should.be.type('string');
.instanceof:構造函數的一個實例
示例:
user.should.be.an.instanceof(User);
.exist():存在
示例:
should.not.exist(err)
.containDeep():深度包含
示例:
[[1],[2],[3, 4]].should.containDeep([[3]]);
.containEql: 包含或等價於
示例:
([1, 2, { a: 10 }]).should.containEql({ a: 10 });
示例
it('當傳入條件為空時修改失敗', function (done) { request.post('/XX') .set('Content-Type', 'application/json') .set('Cookie', cookie) .send({ "data": null }) .expect(200, function (err, res) { should.not.exist(err); res.text.should.containEql('"result":-1'); done(); });
3、chai
簡介
Chai是個流行的斷言庫,聲明式風格更冗長,但看起來更加通順。有三個接口:should、expect 和 assert。它還有用來比較對象、數組和它們的屬性的工具。
比如用typeof
比較類型,用property
檢查某個對象是否有我們想要的屬性。
安裝
npm install chai
示例
//引入斷言庫chai const chai = require('chai'); //使用它的assert斷言風格 const assert = chai.assert; const foo = 'bar'; const tea = { flavors: ['char', 'earl grey', 'pg tips'] }; describe('示例',function() { it('1',function() { assert.typeOf(foo, 'string'); }); it('2',function() { assert.equal(foo, 'bar'); }); it('3',function() { assert.lengthOf(foo, 3); }); it('4',function() { assert.property(tea, 'flavors'); }); it('5',function() { assert.lengthOf(tea.flavors, 3); });
三、supertest測試庫
簡介
用nodejs做web開發的時候,模擬http請求時是必不可少的,當然使用瀏覽器也可以方便的實現http請求測試,但是並不快捷。supertest是一個非常好的適用於node的模擬http請求的庫。
安裝
npm install supertest
方法
.set():用來設置數據
.expect():用來斷言,如:.expect(200)
.end():執行一個request請求,在回調函數里面根據業務邏輯的返回數據做斷言分析。
.send():用來發送表單域數據,比如一個登錄模塊
.attach():主要用來測試文件上傳,由於send()只能上傳文本域,所以關於multipart-file的上傳需要通過附件來綁定。
eg.
describe('< 上傳文件 >', function () { it('條件齊全時上傳成功', function (done) { request.post('/XX') .set('Content-Type', 'multipart/form-data') .set('Cookie', cookie) .field('fileId', '1000100') .attach("file","uploadFile/1.txt") .expect(200, function (err, res) { should.not.exist(err); res.text.should.containEql('"result":1'); done(); }); }); });
說明:
很多業務中,需要用戶先登錄才有權限執行操作,這個時候作為http請求模擬,必須要可以保存一些Cookie數據,也就是Cookie的持久化。