Node.js 24:用内置 test runner 给参数校验做零依赖测试

63 次浏览1 条回复

Node.js 自带的 node:test 足以覆盖不少小型脚本和 CLI,无需先引入测试框架。下面用一个参数校验函数演示最小可运行结构。

环境:Node.js 24.x;Linux、macOS 或 Windows;项目使用 ESM。

先创建 package.json

{
  "type": "module",
  "scripts": {
    "test": "node --test"
  }
}

创建 limit.js

export function parseLimit(raw) {
  const value = Number(raw);

  if (!Number.isInteger(value) || value < 1 || value > 100) {
    throw new RangeError('limit must be an integer from 1 to 100');
  }

  return value;
}

创建 limit.test.js

import test from 'node:test';
import assert from 'node:assert/strict';
import { parseLimit } from './limit.js';

test('accepts the supported boundaries', () => {
  assert.equal(parseLimit('1'), 1);
  assert.equal(parseLimit('100'), 100);
});

test('rejects invalid values', () => {
  for (const input of ['0', '101', '1.5', 'abc', '']) {
    assert.throws(
      () => parseLimit(input),
      { name: 'RangeError' },
      `input: ${JSON.stringify(input)}`
    );
  }
});

运行:

npm test

调试单个用例时,可以按名称过滤:

node --test --test-name-pattern=boundaries

这里有两个值得保留的细节:使用 node:assert/strict,避免宽松相等掩盖类型问题;错误断言先约束错误类型,错误文案以后调整时测试不会无谓失效。对于纯函数、参数解析和小型 CLI,这套结构通常已经够用。

这套用例已经覆盖了数值范围,但 CLI 参数还有一个容易遗漏的边界:Number() 会接受多种数字语法,例如 Number('1e2') === 100Number('0x10') === 16,因此当前实现会放行指数或十六进制形式。

如果参数契约是“只接受十进制数字串 1 到 100”,可以先校验字面形式,再转换:

export function parseLimit(raw) {
  if (typeof raw !== 'string' || !/^(?:[1-9][0-9]?|100)$/.test(raw)) {
    throw new RangeError('limit must be an integer from 1 to 100');
  }

  return Number(raw);
}

对应补一组回归用例:

test('rejects alternate numeric syntax', () => {
  for (const input of ['1e2', '0x10', '01', ' 1 ', '+1']) {
    assert.throws(() => parseLimit(input), { name: 'RangeError' });
  }
});

如果产品希望容忍首尾空格,也建议显式 trim(),并把这一行为写进测试;这样参数语法是由代码契约决定,而不是由 Number() 的隐式转换规则决定。