Javascript單元測試工具-Jest 學習筆記(一)

寫在前面

首先這並非一篇完整的關於Jest的教程,只是我的在接觸jest學習的一點隨手筆記,大部份內容都是對官方文檔的一些翻譯。只是讓想了解jest的人快速知道一下jest是作什麼的,怎麼作。對於如何對項目進行測試,特別是如今很火的React,後面待熟練使用或者會另寫一篇心得體會。javascript

What's Jest

Jest是Facebook開發的一個對javascript進行單元測試的工具,以前僅在其內部使用,後開源,而且是在Jasmine測試框架上演變開發而來,使用了咱們熟知的expect(value).toBe(other)這種斷言格式。java

Getting Start

第一個Jest測試Demo

經過npm安裝android

$ npm install jest --save-dev

編輯一個待測試的sum.js文件以下:git

function sum(a, b) {
    return a + b;
}
module.exports = sum;

編輯一個測試文件sum.test.jsgithub

注意:關於這個測試文件的位置,建議是對每一個組件新建一個__test__文件夾,而後文件命名是name.test.js,用於存放測試文件。正則表達式

const sum = require('./sum');
    
test('adds 1 + 2 to equal 3', ()=> {
    expect(sum(1, 2)).toBe(3);
});

接着在package.json文件裏添加測試命令npm

"scripts:" {
    "test": "jest"
}

最後,運行 npm test命令後jest將會打印以下信息json

PASS ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)

至此,第一個測試Demo完成了。數組

Using Matchers

Jest使用matchers來使用不一樣的方式測試你的結果。promise

Common Matchers

最簡單的測試方式就是測試一個值是否全等

test('2加2等於4', ()=> {
    expect(2 + 2).toBe(4);
});

在上述代碼中,expect(2+2)返回一個「指望」對象,一般咱們不會對這個指望對象進行匹配,而是由matchers完成,在這裏.toBe(4)即是這個matchers,當Jest運行時,它會跟蹤全部失敗的matchers以便打印正確的錯誤信息給咱們。

toBe使用 === 來測試全等於,若是咱們想檢查一個對象object中的值,使用toEqual來替代,toEqual遞歸遍歷檢查對象或數組裏的每個領域。

"use strict";
    
test('object assigenment', ()=> {
    let data = { one: 1};
    data['two'] = 2;
    expect(data).toEqual({ one: 1, two: 2 });
})

注意:官網的例子是沒有使用的"use strict";,而後npm test的時候就會報出一條錯誤
SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

使用not能夠測試一個matchers的反向規則:

test('adding positive numbers is not zero', () => {
    for (let a = 1; a < 10; a++) {
        for (let b = 1; b < 10; b++) {
            expect(a + b).not.toBe(0);
        }
    }
});

Truthiness

在測試的時候,有時候咱們須要在undefinednullfalse進行區別,可是咱們又不想去了解他們的不一樣點,Jest也會幫助咱們獲得咱們想要的結果。

  • toBeNull 檢查是否爲null

  • toBeUndefined 檢查是否爲undefined

  • toBeDefinedtoBeUndefined的相反

  • toBeTruthy 檢查任何經過if顯示轉換是否爲true

  • toBeFalsy 檢查任何經過if顯示轉換是否爲false

以下:

test('null', () => {
    let n = null;
      expect(n).toBeNull();
      expect(n).toBeDefined();
      expect(n).not.toBeUndefined();
      expect(n).not.toBeTruthy();
      expect(n).toBeFalsy();
});

test('zero', () => {
      let z = 0;
      expect(z).not.toBeNull();
      expect(z).toBeDefined();
      expect(z).not.toBeUndefined();
      expect(z).not.toBeTruthy();
      expect(z).toBeFalsy();
});

Numbers

比較數字的大多數方法都有其對應的matchers

  • toBeGreaterThan 大於

  • toBeGreaterThanOrEqual 大於等於

  • toBeLessThan 小於

  • toBeLessThanOrEqual 小於等於

test('two plus two', () => {
    let value = 2 + 2;
    expect(value).toBeGreaterThan(3);
    expect(value).toBeGreaterThanOrEqual(3.5);
    expect(value).toBeLessThan(5);
    expect(value).toBeLessThanOrEqual(4.5);

    // toBe and toEqual 對於number類型做用是同樣的
    expect(value).toBe(4);
    expect(value).toEqual(4);
});

對於浮點數的測試,使用toBeCloseTo來替代toEqual,由於咱們不會讓一個測試依賴於一個微小的舍入型錯誤。

test('adding floating point numbers', () => {
    let value = 0.1 + 0.2;
    expect(value).not.toBe(0.3);    // It isn't! Because rounding error
    expect(value).toBeCloseTo(0.3); // This works.
});

Strings

使用toMatch對字符串進行正則表達式匹配

test('there is no I in team', () => {
    expect('team').not.toMatch(/I/);
});

test('but there is a "stop" in Christoph', () => {
    expect('Christoph').toMatch(/stop/);
})

Arrays

使用toContain對數組內的特定項進行匹配測試

let shoppingList = ['diapers', 'kleenex', 'trash bags', 'paper towels', 'beer'];

test('the shopping list has beer on it', () => {
    expect(shoppingList).toContain('beer');
});

Exceptions

使用toThrow對一個特定函數調用時候拋出的錯誤進行測試

function compileAndroidCode() {
    throw new ConfigError('you are using the wrong JDK');
}

test('compiling android goes as expected', () => {
    expect(compileAndroidCode).toThrow();
    expect(compileAndroidCode).toThrow(ConfigError);

    // You can also use the exact error message or a regexp
    expect(compileAndroidCode).toThrow('you are using the wrong JDK');
    expect(compileAndroidCode).toThrow(/JDK/);
});

Testing Asynchronous Code

在javascript程序中,會常常見到一些異步執行的代碼,當咱們有這些異步執行的代碼時,Jest須要知道當前這個代碼測試是否已經完成,而後才能轉向另外一個測試。Jest提供了一些方法來處理這種問題。

Callbacks

最經常使用的異步測試模式即是callbacks

列如,咱們有一個fetchData(callback)方法,當callback(data)方法調用的時候,咱們會獲取一些data數據,而且想測試返回的數據是否只是一個字符串uyun

默認狀況下下,Jest在全部的代碼執行完以後便會完成測試,這意味這些測試再也不會按計劃的工做下去。

// Don't do this!
test('the data is uyun', () => {
    function callback(data) {
        expect(data).toBe('uyun');
    }

    fetchData(callback);
});

問題是,測試但願一旦fatchData成功後才能完成,並在其以前調用回調。

這裏有另外一種形式修復這個測試的問題,在這個測試方法裏使用一個參數爲done的回調參數,而不是放置一個空參數,Jest要等到done被調用後纔會結束這次測試。

test('the data is uyun', done => {
    function callback(data) {
        expect(data).toBe('uyun');
        done();
    }

    fetchData(callback);
});

若是done()沒被調用,測試即失敗了,這時候咱們也會獲得咱們想要的錯誤結果了。

Promises

若是咱們的代碼中使用到了Promises ,這裏有一個簡單的異步測試處理方法。只是咱們的測試中返回一個promise,而且Jest會等待這個promise解析完成,若是rejected了,這個測試便會自動視爲失敗。以下:

test('the data is uyun', () => {
    return fetchData().then(data => {
        expect(data).toBe('uyun');
    });
});

注意:必定要確保返回了Promise,若是省略了這步,你的測試將會在fetchData完成以前首先結束掉。

Async/Await

若是代碼中使用到asyncawait,能夠這樣作。編寫一個異步測試,僅須要在測試方法前面使用async關鍵詞,而後傳遞給測試函數便可。以下:

test('the data is uyun', async () => {
    const data = await fetchData();
    expect(data).toBe('uyun');
});

在這個例子中,asyncawait等同於promises方法的一種語法糖實現方式。

相關文章
相關標籤/搜索