Node.js:小脚本也可以直接用内置 `node:test` 跑测试

33 次浏览6 条回复

现在 Node 自带测试 runner,小工具里想补一两个断言,不一定要先拉一套 Jest/Vitest。

环境:Node.js 18+。建两个文件:

sum.mjs

export function sum(a, b) {
  return a + b
}

sum.test.mjs

import test from 'node:test'
import assert from 'node:assert/strict'
import { sum } from './sum.mjs'

test('sum adds two numbers', () => {
  assert.equal(sum(2, 3), 5)
})

然后跑:

node --test

正常会看到一段 TAP 输出,失败时也能直接定位到断言。

它不一定适合很大的前端项目,但给 CLI、小库、一次性脚本补基础测试,少装依赖这一点还挺舒服。

这个用在小包里确实轻。补一个小点:如果测试文件多了,可以用名字筛一下:

node --test --test-name-pattern=sum

临时只跑某一组断言会方便些。再配 node:assert/strict,基本不用额外依赖就能把核心函数兜住。

还有个小用法也挺适合脚本仓库:可以直接用 glob 指定测试文件,避免把临时目录里的东西也扫进去。

node --test "test/**/*.test.mjs"

我一般会把这种命令放到 package.jsonscripts.test 里,后面要换 runner 也只改一个地方。

FinleyLv1#2

还有个小用法也挺适合脚本仓库:可以直接用 glob 指定测试文件,避免把临时目录里的东西也扫进去。

node --test "test/**/*.test.mjs"

我一般会把这种命令放到 package.jsonscripts.test 里,后面要换 runner 也只改一个地方。

node:test 里还有个我觉得容易忽略的点:异步测试不用特别包一层,直接写 async 就行。

import test from 'node:test'
import assert from 'node:assert/strict'

test('fetch config', async () => {
  const config = await Promise.resolve({ ok: true })
  assert.equal(config.ok, true)
})

小脚本里测文件读写、HTTP mock 这种会顺手不少。

再补个偏小工具的点:如果只是想确认某个分支会不会走到,可以用 node:test 自带的 mock。

import test from 'node:test'
import assert from 'node:assert/strict'

test('calls logger', (t) => {
  const logger = t.mock.fn()

  logger('ok')

  assert.equal(logger.mock.callCount(), 1)
})

环境要新一点的 Node,老版本这块 API 可能不完整。拿来测 CLI 参数解析、回调有没有触发,挺轻。

还有个适合调试的小开关:单个测试临时想聚焦时,可以写 test.only(...),然后运行时加上:

node --test --test-only

这样不会误跑整套。记得提交前把 only 去掉就行,不然 CI 里如果也带了这个参数会漏测。

超时也可以顺手设一下,测网络请求或者子进程时比较有用:

node --test --test-timeout=5000

默认时间不一定符合小脚本的节奏。短一点能更快发现卡住,长一点也能避免慢机器上偶发失败。