你是否经历过:
-
一行代码改了上线后,某个无关接口突然 500?
-
团队新成员加了字段,结果老功能全挂?
-
Bug 修好了,但谁也不敢上线?
这些不是因为你不会写代码,而是:
你没有测试,或者你的测试靠“手点 + 祈祷”。
本篇我们讲解如何在 Node.js 项目中构建一套完整的:
单元测试 + 接口测试体系 —— 让服务不靠运气上线,而是靠验证。
一、测试的四个层级(你至少要有前两个)
| 层级 | 内容 | 工具 |
|---|---|---|
| 单元测试 | 函数 / 模块的正确性 | Jest / Vitest |
| 接口测试 | HTTP 层请求/响应 | Supertest |
| 集成测试 | 多模块逻辑联合验证 | Playwright / Postman |
| E2E 测试 | 用户完整路径验证 | Cypress / Puppeteer |
推荐组合:Jest + Supertest
二、安装依赖与初始化配置
npm install --save-dev jest supertest cross-env
配置脚本:
"scripts": {
"test": "cross-env NODE_ENV=test jest"
}
你也可以添加 jest.config.js 来管理测试规则与覆盖率选项。
三、单元测试实战(逻辑函数)
// utils/math.js
exports.add = (a, b) => a + b;
// tests/math.test.js
const { add } = require('../utils/math');
test('add 1 + 2 = 3', () => {
expect(add(1, 2)).toBe(3);
});
运行测试:
npm test
四、接口测试实战(结合 app 实例)
// tests/user.test.js
const request = require('supertest');
const app = require('../src/app');
describe('User API', () => {
it('should return user profile', async () => {
const res = await request(app).get('/api/user/profile');
expect(res.status).toBe(200);
expect(res.body.name).toBeDefined();
});
});
可以在测试前初始化数据:
beforeAll(() => setupTestDB());
afterAll(() => closeTestDB());
五、模拟数据与依赖隔离
-
使用 faker 生成随机用户、订单等假数据
-
使用 Jest 的 mock 能力,隔离复杂依赖(如数据库 / 文件操作)
jest.mock('../services/userService');
userService.getUser.mockReturnValue({ id: 1, name: 'Test' });
六、测试目录结构推荐
project-root/
├── src/
│ └── ...
├── tests/
│ ├── unit/
│ ├── api/
│ └── fixtures/ ← mock 数据
└── jest.config.js
七、代码覆盖率报告
开启覆盖率:
npm test -- --coverage
会在控制台和 /coverage/ 文件夹中生成详细报告。
目标建议:
-
函数级别覆盖率 ≥ 80%
-
重点模块 / 常改逻辑 ≥ 90%+
八、常见实践建议
| 项目 | 建议 |
|---|---|
| 接口逻辑 | 测试正常路径 + 异常路径(如缺参数、权限不足) |
| Mock 依赖 | 单元测试尽量 isolate,不依赖 DB 等真实外部服务 |
| 命名规范 | 用例名清晰表达行为,如“should return 403 when unauthorized” |
| CI 结合 | 测试必须跑在 GitHub Actions / GitLab CI 等流程中,拒绝红灯合并 |
总结
你写的不是测试,而是:
-
给未来的你一个交代
-
给协作者一个保障
-
给系统上线一层底气
代码 = 行为 + 说明 + 验证。
测试,就是那个“验证”环节。
2165

被折叠的 条评论
为什么被折叠?



