接口测试入门:从协议到流程,一次搞懂
做接口测试这么多年,我最深的感触是:不懂HTTP协议的测试,就像不会看仪表盘的司机。你凭感觉踩油门,翻车了都不知道问题出在哪。这一节咱们就把核心概念掰开揉碎,配上我踩过的坑,学完就能直接上手。
HTTP协议核心:方法、状态码、头部
HTTP是个啥?说白了,就是客户端和服务端之间“讨价还价”的规矩。你发个请求,我回个响应,一来一回就完事。但这里的门道不少,咱们一个一个看。
HTTP方法:你对资源到底想干嘛?
方法就是告诉服务器:“我要对你的资源做什么”。常见的就这么几个:
| 方法 | 含义 | 幂等? | 安全? |
|---|---|---|---|
| GET | 获取资源 | 是 | 是 |
| POST | 创建资源 | 否 | 否 |
| PUT | 整体更新 | 是 | 否 |
| PATCH | 部分更新 | 通常不幂等 | 否 |
| DELETE | 删除资源 | 是 | 否 |
我见过不少团队把POST当PUT用,同一个订单提交两次,结果下了两个单。这就是没理解幂等性的后果。幂等的意思是:你调一次和调十次,对服务器的最终状态是一样的。GET、PUT、DELETE天生幂等,POST不行。
状态码:一眼能看出问题在哪
状态码是服务器给你的“表情”。我刚开始做测试时,只看200和500,后来发现这么干太粗暴了。你想想看:200不一定代表成功,可能只是请求被正常处理,但业务逻辑报错了。正确做法是:先看状态码区分大类,再看response body里的业务码。
| 范围 | 含义 | 常见码 |
|---|---|---|
| 1xx | 信息 | 你基本用不到 |
| 2xx | 成功 | 200(OK)、201(Created)、204(No Content) |
| 3xx | 重定向 | 301(永久)、302(临时)、304(未修改) |
| 4xx | 客户端错误 | 400(Bad Request)、401(未认证)、403(无权限)、404(不存在)、405(方法不允许)、429(限流) |
| 5xx | 服务端错误 | 500(内部错误)、502(网关超时)、503(服务不可用) |
HTTP头部:藏在信封里的小纸条
头部信息很多,但做接口测试重点关注这几个:
- Content-Type:告诉对端请求/响应体是什么格式。常见的有
application/json、application/x-www-form-urlencoded、multipart/form-data。我记得有一次排查线上问题,客户端传了json但Content-Type写成了form,服务端解析后所有字段都是null,坑了我一上午。 - Authorization:认证凭证,Bearer 或者Basic auth。很多同学写脚本时忘带这个头,然后被401搞崩溃。
- Accept:客户端希望服务端返回什么格式。“我只要json,别给我xml”。
- Cache-Control、ETag、If-None-Match:缓存相关,回归测试时容易忽略——服务端返回304没改,你的断言还按200写?必报错。
RESTful API设计原则
RESTful是对接口设计的一种约定,不是标准。但遵守它,能让你的接口自解释、易测试。我总结几个核心点。
资源路径用名词,不用动词
好的设计:GET /api/users、POST /api/orders。糟糕的设计:GET /api/getUserList、POST /api/createOrder。动词已经在方法里了,路径里再写一遍就是冗余。
用HTTP方法表达动作
获取用GET,创建用POST,整体更新用PUT,部分更新用PATCH,删除用DELETE。我见过有人把所有操作都包装成POST,路径里带action参数,比如 POST /api/order?action=delete。这么做不是不行,但测试脚本里要写很多分支逻辑。你用DELETE,测试框架天然就知道这个接口不该有请求体,返回状态码该是200或204。多清爽。
状态码与业务语义对齐
创建成功返回201(Created),删除成功没内容返回204(No Content)。别所有成功都甩200。我还见过一种“全200派”:业务错误也在响应体里放code=1,HTTP状态码还是200。你想想看,这种设计下,测试自动化里必须每个响应都解析body,代码量翻了倍。能用状态码表达语义的,就别藏到body里。
版本控制放在路径或请求头
常用方式:/api/v1/orders 或者 Headers: Accept: application/vnd.myapp.v1+json。在我之前的项目中,路径版本更直观,测试脚本里直接拼接URL就好。
接口测试基本流程
好了,理论讲完了。咱们来走一遍接口测试的实战步骤。我习惯把流程分为6个环节,配合下面的流程图会更好理解。
第一步:需求分析
别上来就写脚本。先理清楚:这个接口属于哪个业务模块?输入参数有哪些边界值?期望的输出是什么?异常场景有哪些?我最怕测试同学拿着一个“新增用户”的需求,写出来的测试脚本只测了正常注册。密码超长怎么办?用户名已存在?没有传必填字段?这些才是价值所在。
第二步:接口文档评审
拿到文档后,我建议你用工具(curl、Postman、或者一个小脚本)先手动调一遍。不是为了验证,而是为了把文档里的坑找出来。我遇到过文档里写参数是number,实际接口传number报错,必须传string。还有一次,文档说状态码201,但实际返回200。这种问题尽早暴露,不然自动化脚本写出来也是白搭。
第三步:用例设计
接口测试用例设计要比功能测试更聚焦。我常用这几个维度:
- 正常路径:最核心的业务流程
- 边界值:参数最大值、最小值、空值
- 异常场景:参数类型错误、缺少必填字段、重复提交、超时
- 幂等性:同一请求发两次,期望结果一致
- 并发:同时发起多个请求(注意:这不是必须的,看场景)
第四步:脚本开发与数据准备
写脚本我不多说,后面章节会深入。这里强调数据准备。接口测试最怕“依赖前序接口”。比如你得先创建订单才能查询订单。我的做法是:在脚本里把前置数据通过接口调用生成,不要手工去数据库里插数据。为什么?因为手工插的数据在回归时可能被清掉,而接口生成的每次运行都是全新的,可重复。
一个简单的数据准备示例:
// 伪代码:先创建用户,再获取用户信息
POST /api/users { "name":"test01", "email":"test01@example.com" }
// 从响应中取出 userId: 12345
GET /api/users/12345
// 断言 name 为 test01
第五步:执行与断言
执行不仅仅是发请求。你需要在脚本中自动断言:
- 状态码是否符合预期(例如创建返回201)
- 响应体关键字段是否存在、类型是否正确
- 响应时间是否在阈值内(比如接口要求在500ms内)
- 数据一致性(比如创建成功后,再GET一次,数据相符)
如果接口返回了自定义业务码(比如 {"code":0,"msg":"success"}),一定要断言 code===0。我见过200状态码但业务码为-1的情况——服务器说的是“请求收到了,但业务处理失败”。脚本如果只断言200,这个bug就漏了。
第六步:报告与缺陷跟踪
测试报告要清晰:这次跑了多少用例?通过多少?失败多少?失败原因是什么?我最讨厌那种只报告“3个失败”但不告诉你为什么的报告。建议在脚本里把请求URL、请求体、实际响应体和失败断言信息都打印出来。缺陷跟踪别忘了:不是所有失败都是bug,也可能是环境问题、测试数据过期、或文档未同步。要会区分,否则开发看到就会怼回来。