API接口测试
每个 API 端点必测的内容
| 类别 | 测试用例 |
|---|---|
| 正常路径 | 有效输入 → 预期响应体、正确状态码 |
| 参数校验 | 缺少必填字段、类型错误、边界值 |
| 认证 | 无令牌 → 401,令牌过期 → 401,令牌无效 → 401 |
| 授权 | 权限不足 → 403,访问他人数据 → 403 |
| 资源不存在 | 不存在的 ID → 404 |
| 幂等性 | 相同 key 重复 POST → 结果相同,无重复数据 |
| 响应结构 | 所有预期字段存在,类型正确 |
集成测试(Supertest + Node.js)
import request from 'supertest';
import app from '../app';
import { db } from '../db';
describe('POST /api/users', () => {
afterEach(() => db.users.deleteMany({})); // 清理数据
it('创建用户并返回 201', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: '张三', email: 'zhang@example.com' })
.expect(201)
.expect('Content-Type', /json/);
expect(res.body).toMatchObject({
id: expect.any(String),
name: '张三',
email: 'zhang@example.com'
});
});
it('缺少 email 时返回 400', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: '张三' })
.expect(400);
expect(res.body.error).toContain('email');
});
it('邮箱已存在时返回 409', async () => {
await db.users.create({ name: '张三', email: 'zhang@example.com' });
await request(app)
.post('/api/users')
.send({ name: '李四', email: 'zhang@example.com' })
.expect(409);
});
});
Newman CLI 自动化
# 命令行运行 Postman 集合
newman run collection.json \
--environment staging.env.json \
--reporters cli,json \
--reporter-json-export results.json
# Postman Tests 脚本示例
pm.test("状态码为 200", () => {
pm.response.to.have.status(200);
});
pm.test("响应结构正确", () => {
const schema = {
type: "object",
required: ["id", "name", "email"],
properties: {
id: { type: "string" },
name: { type: "string" },
email: { type: "string", format: "email" }
}
};
pm.response.to.have.jsonSchema(schema);
});
// 将令牌保存供后续请求使用
const token = pm.response.json().token;
pm.environment.set("AUTH_TOKEN", token);