跳轉到

5.2 單元測試:node:test 與 Jest#

Node 內建測試:node:test#

Node 18+ 內建測試框架,不用安裝任何套件就能寫測試。

要測試的程式 math.js:

export function add(a, b) {
  return a + b;
}

export function divide(a, b) {
  if (b === 0) throw new Error("除數不可為 0");
  return a / b;
}

測試檔 math.test.js(慣例:檔名加 .test.js):

import { test } from "node:test";
import assert from "node:assert";
import { add, divide } from "./math.js";

test("add 應該正確相加", () => {
  assert.equal(add(1, 2), 3);
  assert.equal(add(-1, 1), 0);
});

test("divide 應該正確相除", () => {
  assert.equal(divide(10, 2), 5);
});

test("divide 除以 0 應該拋錯", () => {
  assert.throws(() => divide(10, 0), /除數不可為 0/);
});

執行測試:

node --test           # 自動找出所有 *.test.js
node --test --watch   # 改程式自動重跑(開發時超好用)

輸出:

✔ add 應該正確相加 (0.5ms)
✔ divide 應該正確相除 (0.3ms)
✔ divide 除以 0 應該拋錯 (0.4ms)

Jest:最流行的測試框架#

大專案與舊專案常見 Jest,語法類似但功能更多(mock、覆蓋率、快照):

npm install -D jest
{
  "scripts": {
    "test": "jest --watchAll"
  }
}

測試寫法:

const { add } = require("./math");

test("add 應該正確相加", () => {
  expect(add(1, 2)).toBe(3);        // toBe:完全相等
  expect(add(1, 2)).not.toBe(4);    // not:反向
});

常用斷言對照#

node:test / assert Jest 用途
assert.equal(a, b) expect(a).toBe(b) 相等(嚴格)
assert.deepEqual(a, b) expect(a).toEqual(b) 物件/陣列深度相等
assert.ok(x) expect(x).toBeTruthy() 為真
assert.throws(fn) expect(fn).toThrow() 應該拋錯

測試的工作流程#

{
  "scripts": {
    "test": "node --test",
    "test:watch": "node --test --watch"
  }
}
  • 開發時:npm run test:watch,改完程式立刻看到測試結果
  • commit 前:npm test 全跑一遍
  • Pull Request:CI 自動跑,不通過不能合併

建議:新專案直接用內建 node:test,零依賴零設定;需要 mock 與覆蓋率再考慮 Jest。