【Jest】第一次的單元測試

對 Unit Test 一直是久聞其名而不見其人,最近剛好有機會碰到,趕緊來生筆記做個紀錄,本文主要內容參考 Jest 官方教學,並以自己便於理解的方式寫成筆記。

目錄

環境建置

使用方式

Jest 運作解析

Matchers
Exceptions

參考資料


環境建置

首先在專案內安裝 Jest(官方預設使用 yarn)

1
2
3
4
5
// yarn
yarn add --dev jest

// npm
npm install --save-dev jest

安裝完畢後,package.json 內就會新增 jest 與版本紀錄,而 script 裡面也會多一個執行 jest 的指令 test。

如果沒有的話,再自行手動新增如下:

1
2
3
4
5
6
7
{
"scripts": {
"test": "jest", // 執行測試
"test": "jest --coverage", // 執行測試 + 產出報告
...
}
}

加上 --coverage 會再回報測試覆蓋率等數據,同時也會產出報告檔案,在跑完測試後可以查看。


使用方式

以下做為示範,先建立一個準備拿來測試用的 example.js 檔案,內容如下:

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

這裡留意要記得 export 程式碼,否則待會建立的測試檔無法引用其內容來進行測試。

接著建立 example.test.js 如下:

1
2
3
4
5
const sum = require('./example');

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

以上兩個檔案的位置,都只要是在 terminal 執行的目錄內就可以了,Jest 會將根目錄範圍內,所有副檔名為 .test.js 的檔案都跑一遍。

準備好後,接著在 terminal 下 yarn testnpm run test,就會回報測試的結果是否通過囉!

1
2
3
4
5
6
7
8
9
10
$ jest
PASS ./example.test.js
√ adds 1 + 2 to equal 3 (2 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.475 s, estimated 1 s
Ran all test suites.
Done in 1.33s.

以上能夠看到測試結果為 PASS,所有 expect 都通過了測試,後面則會列出測試總數、通過數、花費時間等資料。

如果想要更詳細的測試結果,可以在 test 指令後加入 --coverage,除了以上資訊之外,會再列出測試覆蓋率等資料,並於 coverage 資料夾中生成實體報告。


Jest 運作解析

接著來將上面 example.test.js 的內容拿出來仔細檢視看看吧,我們發現測試的部分主要由 test() 這個函式處理,第一個參數放入對這項測試的敘述,第二個參數則是一個函式,測試的內容就放在這個函式內。

在這裡面,expect() 方法會接受要測試的函式,並在執行該函式後回傳一個物件,由接續在後面的 matchers 進行比對。test 中可以放入多個 expect,丟入不同參數和預期結果,看看程式執行是否都符合。

Jest 中有非常多的 matchers,用不同方式來驗證執行結果是否符合預期,所有方法可參考 Expect(官網),以下則列出常見的一些 matchers。


Matchers

  • toBe:使用 Object.is() 來驗證執行結果與預期結果是否相符
  • toEqual:以遞迴方式驗證 object 或 array 裡是否每個元素都相符
  • not:加在其他 matchers 前面,表示測試結果應該要「不符合」

測試真值:

  • toBeNull:回傳值是否為 null
  • toBeUndefined:回傳值是否為 undefined
  • toBeDefined:回傳值是否不為 undefined
  • toBeTruthy:使用 if 時判定為真
  • toBeFalsy:使用 if 時判定為假

測試數值:

  • toBeGreaterThan:大於
  • toBeGreaterThanOrEqual:大於等於
  • toBeLessThan:小於
  • toBeLessThanOrEqual:小於等於
  • toBeCloseTo:浮點數的計算使用,避免小數點誤差而報錯
    1
    2
    3
    4
    5
    test('adding floating point numbers', () => {
    const value = 0.1 + 0.2;
    //expect(value).toBe(0.3); // 這條會因為浮點數計算誤而不符
    expect(value).toBeCloseTo(0.3); // 測試浮點數正確寫法
    });

測試字串:

  • toMatch:以正規表示式測試回傳字串內是否包含特定字串

測試陣列 / 可迭代物件:

  • toContain:可迭代物件的內容中是否有任意內容相符

Exceptions

  • toThrow:如果執行函式時報錯,可以承接報錯內容
    如果不希望在執行被測試內容時由於報錯而中斷,而是連 exceptions 都如實表示,可以使用 toThrow
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function compileAndroidCode() {
    throw new Error('you are using the wrong JDK');
    }

    test('compiling android goes as expected', () => {
    expect(() => compileAndroidCode()).toThrow();
    expect(() => compileAndroidCode()).toThrow(Error);
    expect(() => compileAndroidCode()).toThrow('you are using the wrong JDK');
    expect(() => compileAndroidCode()).toThrow(/JDK/);
    });

Jest 還有很多內容,以上僅按照官網教學列出簡單的筆記,之後如果有繼續了解的話,就再接下去寫更深入的內容吧。



參考資料

Jest 官網教學
Jest | 讓 Jest 為你的 Code 做測試-基礎用法教學