服务端接口测试-接口测试的测试点【杭州多测师】【杭州多测师_王sir】
接口测试与系统功能测试的关注点没有太多不同,只是我们直接面对的测试对象由页面变成了接口。
本文以HTTP(S)协议接口为例,归纳总结了单接口测试时的测试点。
1. 什么是接口
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
当我们想学习如何做接口测试时,来到CSDN或其他技术平台,在搜索框内输入关键字“接口测试”,点击搜索,等待1-2秒后,就能看到页面展示了相关的搜索结果。在这个过程中我们按F12打开开发者工具,切换到network,可以看到,在点击搜索后,前端页面根据我们输入的关键词向后端服务器发送了一个请求(request),服务端收到请求并处理完成后返回相应结果(response)。
接口请求和返回示例由于用户可能绕过前端页面的逻辑,直接调用接口,因此需要考虑直接调用接口进行测试,确定接口是否能在功能、可靠性、性能和安全方面达到预期。从功能测试的角度来看,我们需要关注输入关键词和输出结果数据,接口测试在这方面的关注点也基本是一样的。
2. 输入参数和输出结果
在记账本中,用户在下面的页面上选择、填入必要信息后,点击完成,会调用接口新增一条支出记录。
记一笔可以看到,输入参数共有6个,接口测试时需要对这六个输入参数进行测试:
amount
参数值数值类型,那么根据等价类和边界值方法,需要根据需求验证数值大小范围,小数及其位数,负数,其他非法字符类型;date
为字符串类型,但表示的是日期,用户在前端页面选择日期,日期的格式也有前端逻辑完成,但直接调用接口时,同样需要验证日期格式:合法的日期,不合法的日期如2021-13-01,其他字符类型;category
表示支出/收入的类别,表面看是字符串类型的,但结合功能逻辑,该参数只能接收枚举值,即用户配置过的类别中的其中一个,这种枚举值参数需要遍历所有合法的枚举值,再验证任意不在枚举值内的其他值;type
和category
一样,也是枚举值类型,只能是"EXPENSE"和 "INCOME";- 在这里还有很重要的一点要注意,
category
和type
实际上是存在对应关系的,比如早餐这一类别只在支出中设置了,当我们传参为{"category": "breakfast", "type": "INCOME"}
时,预期是不能成功创建的,即对于组合参数,需要验证参数的组合方式; img_id
为数组类型,业务上来说数组内元素代表上传图片的id,id为字符串类型,需要验证元素总个数:空数组、有效个元素、超出有效范围的个数,数组内单个元素即id有效性验证:有效的图片id、无效的图片id、空字符串等,还有数组内元素重复;note
为字符串类型,为该账单的备注,需要验证字符串中的字符类型:中文、英文、特殊字符如空格!@%*和emoji等,还有字符串长度,如果该内容是用户评论、用户名、UGC文章内容等,通常还需要验证是否有做敏感词过滤;- 根据需求,金额、日期、分类和类型是必填项,图片和备注是选填项,在测试时也需要覆盖到这一点。
除了输入参数,输出结果也是需要测试的:
- 最重要的一点当然是当我使用正确的参数发请求后,能够收到正确的响应:返回码为200,返回json中各值均正确;
- 当传入不合法的参数时,对于所有可能出现的业务错误,code和message都能对应给到清晰明确的提示,让用户知道自己哪里操作有误;
- 由于其他原因导致服务器无法正确响应时,也应返回统一的错误码提示用户;
- 有些任务处理要花费很长时间,这就会导致接口超时,接口超时后前端不应再接收返回响应。
其他叮嘱:
- 分页接口中pageSize参数也应当设计成枚举类型,比如前端只能切换为10/20/50条每页,那么如果我们pageSize传参为100,接口报错,而不应该返回100条数据
- 接口在不应该暴露任何后端接口名称、不打印堆栈等信息
3. 业务逻辑
约束条件
约束条件的测试在功能测试中经常遇到,在接口测试中更为重要。它的意义在于:用户进行操作时,在该操作的前端可以已经进行了约束条件的限制,故用户无法直接触发请求该接口。但是实际上,如果有其他手段:例如 UI 有 bug 或者通过技术手段直接调用接口,那么接口是否针对这些条件进行了限制就更为重要。
某公司发现,价值 100 元的商品,在该公司网上商城被以 0.01 元买走了很多。攻城狮们火速定位,问题原因很快被找到了,原来是购买商品接口的 bug。该接口需要 3 个参数:商品 id、商品单价、购买数量,而服务器根据接口传过来的商品单价(0.01 元)生成了订单。服务器本应根据数据库中的商品单价 100 元来生成订单。我们将单价修改后,再购买,提交到服务器的商品单价就是 0.01 元。这个接口在设计阶段就已经存在问题,正确应该是后台程序根据传入的商品id,查询到对应商品的价格,而不应该直接使用接口传入的价格。
业务功能中最常见的约束条件主要有数值限制、状态限制、关系限制和权限限制,以在购物网站下单时使用优惠券为例:
{ "product_id": "12345678890644", "count": 2, "coupon_id": "thisiscouponid" }
- 数值限制
- 用户购买的商品只有在订单总金额达到300时才可使用该优惠券下单成功
- 订单中商品库存大于等于2时才可以下单成功
- 状态限制
- 只能使用在有效期内的优惠券(同时也是时间限制)
- 只能使用未使用状态的优惠券
- 关系限制
- 只能使用与当前用户账号绑定的优惠券
在上面的接口参数中,我们其实并没有传入用户ID等内容,用户的身份鉴别通常是通过headers中的Token等实现的。
权限限制
权限限制我需要单独拎出来讲,它很重要!
很多系统中都存在系统管理员、普通用户等不同角色的用户,系统管理员拥有一些普通用户没有的权限,比如系统管理员可以发布公告,而普通用户则只能查看,系统管理员和用户还有组织上的划分,比如深圳市的系统管理员和普通用户,广东省的管理员和普通用户。
横向越权和纵向越权就用户角色而言,需要验证低等级用户拥有管理员权限等高于自身级别访问能力,即纵向越权;就用户组织维度来看,需要验证相同组织/不同组织间,是否能访问到不属于自己权限内的资源,即横向越权。
状态转换
很多被测逻辑可以抽象成状态机,各个状态之间根据功能逻辑,能够从一个状态转换到另一个状态。如果我们打乱了这个次序,从一个状态切换到另一个不在它下一状态集中的状态,那么逻辑将会打乱,就会出现逻辑问题。以一个二级审核功能为例,某UGC平台内,用户提交了一篇文章,要先经过初审,初审通过后才能再进行复审,即两轮审核都通过时,文章才能发布出来。
状态转换 - 二级审核针对这种状态转换的逻辑,我们需要验证:
- 正常的状态切换:用户提交 -> 初审通过 -> 复审通过 -> 文章发布成功
- 非正常的状态切换:
- 用户提交 -> 初审驳回 -> 复审通过
- 用户提交 -> 复审通过
4. 幂等性
一个HTTP方法是幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。在正确实现的条件下,GET,HEAD,PUT和DELETE 等方法都是幂等的,而 POST 方法不是。
举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条,这就没有保证接口的幂等性、只要调用接口成功,外部对接口的多次调用得到的结果是相同的,即执行多次和一次的效果是一样的,用户在后续再支付时,不会重复扣款。
接口幂等性测试,需要测试人员在需求分析的时候,就能识别出需要实现幂等的接口,并提前要求开发同学去实现。
5. 文件上传/下载接口
文件的上传下载也是很多产品里会有的功能了。在测试文件上传/下载接口基本功能时,主要还是从文件本身的属性来考虑,即文件名称、文件类型、文件大小、文件内容/规格。
- 文件上传
- 文件名称:文件名的字符串长度;文件名中的特殊字符如空格、@#¥%-等
- 文件类型:验证文件后缀名,保证使用的是白名单
- 文件大小校验:上传文件请求头等也有大小,必须校验的是文件本身的大小
- 文件内容/规格校验:若上传的文件需要后台解析其内容,当然也需要测试填入不同内容;规格主要指图片/视频的尺寸和时长等限制
- 文件上传成功后服务器保存的文件与上传的文件内容一致
- 文件下载
- 文件本身:验证下载的文件的文件名;下来的文件可以正常打开并查看,内容与上传时的一致/内容正确
- 文件下载链接敏感文件内容使用一次性下载链接/短时间内有效下载链接(如身份证图片)
6. 总结
接口测试的测试点
- 输入参数
- 参数值类型
- 数值
- 不同大小的数值(等价类和边界值法)
- 符号:负号 (-),小数点 (.)
- 不同大小的数值(等价类和边界值法)
- 字符串
- 字符串内容
- 中文、英文大小写、颜文字、emoji等
- 特殊字符%@#¥*/等
- 空格,回车符等
- 敏感词
- 中文、英文大小写、颜文字、emoji等
- 字符串长度
- 空串,最小长度,最大长度,超出最大长度等(等价类和边界值法)
- 空串,最小长度,最大长度,超出最大长度等(等价类和边界值法)
- 字符串内容
- 数组
- 数组长度
- 正常范围和超出正常范围(等价类和边界值法)
- 正常范围和超出正常范围(等价类和边界值法)
- 数组内参数
- 主要也是数值和字符串类型
- 部分参数不合法
- 部分参数重复
- 主要也是数值和字符串类型
- 数组长度
- 枚举值
- 传入枚举值
- 传入非枚举值
- 传入枚举值
- 数值
- 必填/非必填
- 不传某参数
- 参数值为空
- 不传某参数
- 组合参数
- 合法的组合:1 - a/b; 2 - c/d
- 不合法的组合
- 合法的组合:1 - a/b; 2 - c/d
- 参数值类型
- 针对业务逻辑测试
- 约束条件
- 数值限制
- 业务对象存在个数限制
- 业务对象存在个数限制
- 日期限制
- 业务对象本身有日期限制
- 限时活动
- 业务对象本身有日期限制
- 状态限制
- 验证业务对象的状态,如新用户,优惠券使用状态等
- 验证业务对象的状态,如新用户,优惠券使用状态等
- 关系限制
- 只能操作已与用户绑定的资源
- 只能操作已与用户绑定的资源
- 权限限制
- 管理员,普通用户
- 是否有操作权限:身份鉴权
- 是否有访问某些数据的权限:横向越权和纵向越权
- 管理员,普通用户
- 数值限制
- 状态转换
- 状态1可以直接到状态2
- 状态1不能直接到状态3
- 状态1可以直接到状态2
- 幂等性
- 同样的请求被执行一次与连续执行多次的效果是一样的
- POST方法不一定是幂等的
- 提前识别需要实现幂等性的接口
- 同样的请求被执行一次与连续执行多次的效果是一样的
- 约束条件
- 输出结果
- 返回码
- 错误原因
- 明确的业务提示
- 不暴露后端接口名称、不打印堆栈等信息
- 明确的业务提示
- 结果
- 不能有接口返回无限条结果数据
- 正确的业务结果
- 不能有接口返回无限条结果数据
- 返回码
- 文件上传和下载
- 文件上传
- 文件名称
- 文件名的字符串长度
- 文件名中的特殊字符如空格、@#¥%-等
- 文件名的字符串长度
- 文件类型
- 验证文件后缀名,保证使用的是白名单
- 验证文件后缀名,保证使用的是白名单
- 文件大小校验
- 上传文件请求头等也有大小,必须校验的是文件本身的大小
- 上传文件请求头等也有大小,必须校验的是文件本身的大小
- 文件内容/规格校验
- 若上传的文件需要后台解析其内容,当然也需要测试填入不同内容
- 规格主要指图片/视频的尺寸和时长等限制
- 若上传的文件需要后台解析其内容,当然也需要测试填入不同内容
- 文件上传成功后服务器保存的文件与上传的文件内容一致
- 文件名称
- 文件下载
- 文件本身
- 验证下载的文件的文件名
- 下来的文件可以正常打开并查看,内容与上传时的一致/内容正确
- 验证下载的文件的文件名
- 文件下载链接敏感文件内容使用一次性下载链接/短时间内有效下载链接(如身份证图片)
- 文件本身
- 文件上传
- 接口测试中的常见BUG
- 传入参数处理不当,导致程序崩溃;
- 传入参数未做限制,生成不符合业务逻辑的数据;
- 类型溢出,导致数据写入和读出不一致;
- 未校验对象权限,用户可以访问到其他用户敏感信息;
- 状态处理不当,导致业务逻辑出现错乱;
- 逻辑校验不完善,可利用漏洞获取非正当利益。
- 传入参数处理不当,导致程序崩溃;