1. Node.js测试运行器初体验
上周在重构一个老项目时,我偶然发现Node.js从v18开始内置了test模块。这个原生测试方案用起来意外地顺手,今天就用三分钟带大家快速上手,感受下不用装任何第三方库就能写单元测试的快乐。
作为对比,之前我们团队一直用Jest+Mocha的组合,虽然功能强大但配置繁琐。而Node.js自带的test模块开箱即用,特别适合小型项目快速验证逻辑,或者给脚本添加基础测试保障。下面我会用实际案例演示如何用不到20行代码搭建完整的测试环境。
2. 测试环境搭建与基础用法
2.1 模块引入与测试结构
新建一个测试文件math.test.js,基础结构如下:
import { test } from 'node:test'; import assert from 'node:assert'; // 待测试的函数 function sum(a, b) { return a + b; } // 测试用例 test('加法函数测试', () => { assert.strictEqual(sum(1, 2), 3); });关键点说明:
- 从
node:test导入的test函数是测试入口 node:assert提供了各种断言方法- 每个
test()定义一个测试用例
运行测试只需执行:
node math.test.js2.2 常用断言方法实战
assert模块提供了丰富的断言方法,最常用的有:
test('各种断言示例', () => { const obj = { a: 1 }; // 严格相等 assert.strictEqual(1, 1); // 深度相等 assert.deepStrictEqual(obj, { a: 1 }); // 验证异常 assert.throws(() => { throw new Error('错误示例'); }); });提示:优先使用
strictEqual而非equal,避免隐式类型转换带来的意外结果。
3. 高级测试技巧
3.1 异步测试的两种写法
处理异步代码时,可以:
// 回调写法 test('回调式异步', (done) => { setTimeout(() => { assert.ok(true); done(); }, 100); }); // Promise写法 test('Promise异步', async () => { const result = await Promise.resolve(42); assert.strictEqual(result, 42); });3.2 测试套件组织
用describe创建测试分组:
import { describe, test } from 'node:test'; describe('数学运算套件', () => { test('加法', () => { assert.strictEqual(1 + 1, 2); }); test('乘法', () => { assert.strictEqual(2 * 3, 6); }); });3.3 测试生命周期钩子
describe('带生命周期的测试', () => { before(() => console.log('整个套件开始前')); after(() => console.log('整个套件结束后')); beforeEach(() => console.log('每个测试开始前')); afterEach(() => console.log('每个测试结束后')); test('示例测试', () => { assert.ok(true); }); });4. 实战对比与选型建议
4.1 与Jest/Mocha的对比
| 特性 | Node.js test | Jest | Mocha |
|---|---|---|---|
| 内置支持 | ✅ | ❌ | ❌ |
| 零配置 | ✅ | ❌ | ❌ |
| 代码覆盖率 | ❌ | ✅ | 需插件 |
| Mock功能 | 基础 | 强大 | 需插件 |
| 断言库 | 基础 | 丰富 | 需配置 |
4.2 适用场景建议
推荐使用Node.js内置测试器当:
- 快速验证工具函数
- 小型CLI工具测试
- 不想引入额外依赖时
- 需要与Node版本保持同步
建议用Jest/Mocha当:
- 需要完整Mock系统
- 需要生成覆盖率报告
- 项目已有相关配置
- 需要丰富插件生态
5. 常见问题排查
Q1: 测试不执行怎么办?
- 检查文件后缀必须是
.test.js或.spec.js - 确认Node版本≥18.0.0
- 确保没有语法错误
Q2: 如何只运行特定测试?
node --test-only math.test.jsQ3: 如何获取代码覆盖率?虽然原生不支持,但可以通过c8工具实现:
npx c8 node math.test.js6. 性能优化技巧
- 并行执行:默认并行运行测试,可通过
{ concurrency: 1 }禁用 - 过滤慢测试:用
--test-name-pattern过滤特定测试 - 减少IO操作:Mock文件系统操作提升速度
test('慢测试', { concurrency: 1 }, async () => { // 需要独占资源的测试 });这个原生测试方案最让我惊喜的是它的执行速度。实测对比同项目测试集:
- Jest: 2.3s
- Node test: 1.1s
对于追求轻量化的场景,这确实是个不错的选择。不过要注意它目前还不支持浏览器环境测试,这是与Jest的主要差距之一。