功能测试流程与自动化脚本
8.7 API测试实战
Tip
前端只能防君子,后端防不了小人。如果你只在 UI 层做拦截,黑客用一个脚本就能绕过你的防御。API 测试就是绕过漂亮的皮囊,直接去拷问灵魂。
1. 为什么要学这个?
你的前端页面做得很完美:输入框限制了只能输正整数,最大值不能超过 100。
你觉得万无一失了。
但黑客根本不打开你的网页。他打开了 Postman (或者直接写代码),直接向你的 API 发送了一个请求:
POST /api/buy { price: -9999 }
如果你的后端没有专门的测试来防御这种“不走寻常路”的请求,你的公司明天就要破产。
2. 核心概念:无头浏览器 (Headless Request)
API 测试 = 没有显示器的浏览器。 它不渲染 CSS,不加载图片,不执行 JS 动画。 它只做最纯粹的 HTTP 交互: 发送 Request -> 拿回 Response -> 尸检 (Assert)
因为省去了渲染过程,它的速度极快 (10ms 级别),比 UI 测试快 100 倍。
3. 代码实战 (api.spec.ts)
Playwright 不仅能测 UI,内置的 request 对象也能完美胜任 API 测试。
import { test, expect } from '@playwright/test';
test.describe('API 安全防线', () => {
// ✅ 场景一:正常查询
test('GET /api/user 应返回当前用户信息', async ({ request }) => {
// 1. 直接发请求,不需要 page.goto
const res = await request.get('/api/user', {
params: { id: '10086' }
});
// 2. 验证:状态码必须是 200 OK
expect(res.ok()).toBeTruthy();
// 3. 验证关键数据:不能泄露密码
const data = await res.json();
expect(data.id).toBe('10086');
expect(data.password).toBeUndefined(); // 这里的 Undefined 就是安全感
});
// ❌ 场景二:恶意攻击
test('POST /api/buy 负数金额应被拦截', async ({ request }) => {
// 模拟黑客行为:直接发负数
const res = await request.post('/api/buy', {
data: {
amount: -100, // 假如我买 -100 个,是不是倒给我钱?
productId: 'ps5'
}
});
// 验证:后端必须返回 400 Bad Request,而不是 200
expect(res.status()).toBe(400);
const body = await res.json();
expect(body.error).toContain('Invalid amount');
});
});
4. 什么时候用 API 测试?
- 测安全性:防注入、防负数、防越权。
- 测极速反馈:UI 测试跑完要 10 分钟,API 测试只要 10 秒。适合每次提交代码前跑一遍。
- 测数据逻辑:比如“注册后数据库里真的多了一条记录吗?”
5. 真实案例
Story
“负数价格”的 PS5
某电商平台曾发生过一起离谱的盗窃案。
攻击者发现前端页面限制了购买数量不能小于 1。
但他通过抓包工具拦截请求,手动把数量改成了 -5。
后端逻辑是:用户余额 = 当前余额 - (单价 * 数量)。
代入公式:余额 = 余额 - (500 * -5) = 余额 + 2500。
结果:他不仅买到了东西,余额还越买越多。
Vibe 心法:永远不要相信客户端发来的数据。前端校验只是为了提升用户体验(少弹窗),后端校验才是保命的防线。API 测试就是用来确信:即使前端不存在,后端依然固若金汤。
6. 本章小结
- 快:API 测试是性价比最高的测试。
- 狠:专门测那些前端 UI 上点不出来的异常值。
- 准:直接验证 JSON 数据,不看样式眼色。