第2章:HTTP协议核心——请求方法、状态码、头信息与状态管理
做接口测试,说白了就是在跟 HTTP 协议打交道。你发的每一个请求,收的每一个响应,底层都是协议在说话。我刚开始接触接口时,总觉得协议是理论课的东西,直到有一次线上事故——某个同事把 GET 请求硬改成 POST,结果缓存层全挂了,用户数据刷不出来。嗯,从那时起我才真正意识到:协议规则不是摆设,它是接口系统的骨架。
2.1 请求方法:你用什么方式跟服务器说话
HTTP 定义了一组“动词”,告诉服务器你想干什么。最常用的就四个:GET、POST、PUT、DELETE。我把它们的核心区别整理成一张表,方便你对照。
| 方法 | 语义 | 请求体 | 幂等性 | 常见用途 |
|---|---|---|---|---|
| GET | 查询资源 | 无 | 是 | 获取列表、详情 |
| POST | 创建资源 | 有 | 否 | 新增订单、提交表单 |
| PUT | 全量更新资源 | 有 | 是 | 修改用户信息 |
| DELETE | 删除资源 | 可有可无 | 是 | 删除记录 |
关键原则:GET 请求不能带请求体,也不应该有副作用。我见过有人把大批量查询参数塞进 GET 的 URL 里,结果 URL 超长被网关截断——接口直接返回 414。用 POST 才能放心传大量数据。
2.2 状态码:服务器在告诉你什么
状态码是服务器给你的一张“脸色”。我把它分成五个区间,每个区间一个意思。你测试时只要记住:2xx 正常,4xx 你错了,5xx 服务器炸了。
- 2xx 成功
200 OK— 正常返回201 Created— 创建成功(POST 常用)204 No Content— 删除成功,响应体为空
- 3xx 重定向
301/302— 资源迁移,接口测试中很少直接处理,但要注意测试用例里不要被跳转迷惑
- 4xx 客户端错误
400 Bad Request— 参数格式错误401 Unauthorized— 没登录403 Forbidden— 权限不够404 Not Found— 接口地址写错了405 Method Not Allowed— 方法不支持(比如接口只接受 POST,你用 GET 就返这个)429 Too Many Requests— 限流了
- 5xx 服务端错误
500 Internal Server Error— 代码抛异常了502 Bad Gateway— 网关或反向代理挂了503 Service Unavailable— 服务过载或维护中
我曾经踩过的坑:某个接口在异常时返回了 200,但响应体里塞了一个 errorCode 告诉调用方失败了。测试脚本没检查 body 里的错误码,结果认为所有 200 都是成功的——线上出了严重误报。记住:状态码只代表协议层面的成功,不代表业务成功。测试断言必须同时检查状态码和业务字段。
2.3 请求头与响应头:藏在信封里的元信息
HTTP 头和信封上的收件人地址、邮戳一样,告诉双方怎么处理这封信。你在测试中最常打交道的头我列在下面:
| 头字段 | 方向 | 说明 | 测试关注点 |
|---|---|---|---|
Content-Type |
请求/响应 | 告诉对方数据格式,比如 application/json |
如果设了 JSON 但 body 格式不对,会返回 415 |
Authorization |
请求 | 携带令牌(Bearer / Basic Auth) | 缺失或过期 → 401 |
Accept |
请求 | 客户端期望的响应格式 | 匹配不对可能返回 406 |
Set-Cookie |
响应 | 服务端下发 Cookie | 需要后续请求自动带上 |
Cache-Control |
响应 | 控制缓存策略 | 测试接口是否被错误缓存 |
Location |
响应 | 重定向目标地址(配合 3xx) | 确认跳转路径正确 |
我建议你用抓包工具(比如 Charles 或浏览器的 DevTools)观察一次完整的登录流程。看看请求先发 POST /login,服务端返回 Set-Cookie,然后后续请求在 Cookie 头里带着它——这样你才能真正理解“无状态协议”是怎么通过头信息实现有状态的。
2.4 Cookie 与 Session:让无状态协议记住你是谁
HTTP 本身是无状态的——每个请求都是独立的孤儿。但业务需要“登录后不要每次都输密码”。于是有了 Cookie 和 Session 这对搭档。
Cookie 的工作流:
- 客户端 POST 用户名密码给登录接口
- 服务端验证通过,生成一个 Session ID,存在内存或 Redis 里
- 服务端在响应头加
Set-Cookie: sessionid=abc123 - 浏览器自动保存这个 Cookie,后续请求自动带上
Cookie: sessionid=abc123 - 服务端根据 sessionid 查 Session 数据,知道你是哪个用户
个人小习惯:在接口测试脚本里,我会用一个全局的 cookies_dict 来维护登录后的 Cookie。每次发送请求前,用 session.cookies.update() 把响应的 Set-Cookie 同步进去。千万不要手动拼接 Cookie 字符串,容易漏掉 Domain、Path 属性。
import requests
session = requests.Session()
# 登录
resp = session.post('https://api.example.com/login', json={'user':'admin','pass':'123'})
# session 对象自动处理了 Set-Cookie,后续请求直接用
resp2 = session.get('https://api.example.com/profile')
print(resp2.json())
用 Session 对象是你最稳妥的做法。它会自动跟踪 Cookie,也支持手动设置 headers。你想想看,如果每个接口都要你自己从响应里抠出 Cookie 再塞进下一个请求,不仅麻烦还容易出 bug。
注意事项:Cookie 有 HttpOnly 和 Secure 标志。HttpOnly 的 Cookie 无法被 JavaScript 读取,能防 XSS 攻击。你在做 Web 端测试时,如果发现 JS 读不到 Cookie,别慌,那是安全设计。另外 Secure 标志要求 Cookie 只在 HTTPS 下传输,测试环境如果走 HTTP 会发送失败。
2.5 本章知识体系一图揽
好了,这张图把本章四个核心知识块串起来了。你写测试用例时,记住从 方法语义 → 状态码预期 → 头信息验证 → 会话保持 这四个维度去设计,覆盖率就基本到位了。
我个人建议你每次接到新接口,先拿 Postman 手工调通一遍,确认方法和头都正确,再写自动化。不要一上来就写代码,那样很容易被协议细节绊倒。