測試
設定
測試 Mithril.js 應用程式相對容易。最簡單的入門方式是使用 ospec、mithril-query 和 JSDOM。安裝它們非常簡單:開啟終端機並執行以下指令。
npm install --save-dev ospec mithril-query jsdom
設定它們也相對簡單,只需幾個簡單的步驟:
- 在
package.json
檔案中,將"test": "ospec"
新增到 npm 指令碼中。最終會看起來像這樣,可能還會有一些與專案相關的額外欄位:
{
"name": "my-project",
"scripts": {
"test": "ospec --require ./test-setup.js"
}
}
- 建立一個設定檔
test-setup.js
,內容如下:
var o = require('ospec');
var jsdom = require('jsdom');
var dom = new jsdom.JSDOM('', {
// 為了取得 `requestAnimationFrame`
pretendToBeVisual: true,
});
// 設定 Mithril.js 運作所需的全域變數。此外,前兩個通常
// 於測試中也很有用。
global.window = dom.window;
global.document = dom.window.document;
global.requestAnimationFrame = dom.window.requestAnimationFrame;
// 載入 Mithril.js 以確保其正確載入。
require('mithril');
// 現在,確認在測試結束時關閉 JSDOM。
o.after(function () {
dom.window.close();
});
- 建立一個元件,例如
src/my-component.js
,內容如下:
function MyComponent() {
return {
view: function (vnode) {
return m('div', vnode.attrs.text);
},
};
}
module.exports = MyComponent;
- 最後,建立一個測試檔案,例如
src/tests/my-component.js
,內容如下:
var mq = require('mithril-query');
var o = require('ospec');
var MyComponent = require('../my-component.js');
o.spec('MyComponent', function () {
o('things are working', function () {
var out = mq(MyComponent, { text: 'What a wonderful day to be alive!' });
out.should.contain('day');
});
});
完成所有設定後,在您安裝所有內容的同一個終端機中,執行此命令。
npm test
如果您已正確設定所有內容,您應該會看到類似以下的輸出:
––––––
All 1 assertions passed in 0ms
最佳實務
在大多數情況下,測試相當簡單。每個測試通常包含三個部分:設定狀態、執行程式碼、檢查結果。但在您測試時,您需要記住一些事項,以確保您獲得最大的效益與價值,並幫助您節省大量時間。
首先也是最重要的,您希望盡可能在流程的早期階段撰寫測試。您不需要 立刻 編寫測試,但至少希望在編寫程式碼的同時編寫測試。這樣,如果事情沒有按照您想像的方式運作,您現在只需花 5 分鐘,就能確切知道發生了什麼事,而不是 6 個月後,當您嘗試發布那個現在已經完全無法運作的驚人應用程式想法時,卻要連續花費 5 天。您不會想陷入那樣的情況。
測試 API、測試行為,但不要測試實作。如果您需要測試在發生特定動作時是否觸發了事件,這樣一切都很好,並且可以隨意進行。但不要在測試中驗證整個 DOM 結構。您不希望僅因為新增了一個與樣式相關的簡單類別,就必須重寫五個不同測試的一部分。您也不希望僅僅因為您向物件新增了一個新的實例方法,就重寫所有測試。
不要害怕重複自己做的事,只有當您在同一個檔案中實際執行相同的事情數十到數百次,或者當您明確產生測試時,才進行抽象化。通常,在程式碼中,當您重複相同的邏輯超過 2-3 次時,將其抽象化為函式會是個好主意,但是當您進行測試時,即使存在大量重複的邏輯,這種冗餘也有助於在對測試進行除錯時為您提供上下文。請記住:測試是規格,而不是普通的程式碼。
單元測試
單元測試會隔離應用程式的各個部分,通常是單個模組,但有時甚至是單個函式,並將它們作為單個「單元」進行測試。它會檢查在給定特定輸入和初始狀態的情況下,它是否產生所需的輸出和副作用。這一切看起來似乎很複雜,但我保證,實際上並不是這樣。以下是 JavaScript 的 +
運算子應用於數字的幾個單元測試範例:
o.spec('addition', function () {
o('works with integers', function () {
o(1 + 2).equals(3);
});
o('works with floats', function () {
// 是的,感謝 IEEE-754 浮點數的怪異之處。
o(0.1 + 0.2).equals(0.30000000000000004);
});
});
就像您可以對簡單的東西進行單元測試一樣,您也可以對 Mithril.js 元件進行單元測試。假設您有這個元件:
// MyComponent.js
var m = require('mithril');
function MyComponent() {
return {
view: function (vnode) {
return m('div', [
vnode.attrs.type === 'goodbye' ? 'Goodbye, world!' : 'Hello, world!',
]);
},
};
}
module.exports = MyComponent;
您可以輕易地為其建立一些單元測試。
var mq = require('mithril-query');
var MyComponent = require('./MyComponent');
o.spec('MyComponent', function () {
o("says 'Hello, world!' when `type` is `hello`", function () {
var out = mq(MyComponent, { type: 'hello' });
out.should.contain('Hello, world!');
});
o("says 'Goodbye, world!' when `type` is `goodbye`", function () {
var out = mq(MyComponent, { type: 'goodbye' });
out.should.contain('Goodbye, world!');
});
o("says 'Hello, world!' when no `type` is given", function () {
var out = mq(MyComponent);
out.should.contain('Hello, world!');
});
});
如同前面提到的,測試是規格。您可以從測試中看到元件應該如何運作,並且該元件能夠非常有效地實現了它。