在接口测试过程中,用例设计是关键中的关键,需要重点关注的一些维度
接口测试
什么是接口
接口就是内部模块对模块,外部系统对其他服务提供的一种可调用或者连接的能力的标准,所谓的接口是模块与模块之间的一种连接
接口测试
上图为一个典型的接口,一个接口通常是有输入输出的,输入就是我们常见的入参,输出有时有,有时没有。调用相关接口,接口会执行相关处理逻辑
接口测试的用例设计,主要从输入和接口处理两方面考虑:
- 针对输入,可按照参数类型进行设计
- 针对接口处理,可按照逻辑进行用例设计
- 针对输出,可根据结果进行分析设计
典型问题
接口测试经常遇到的bug和问题,如下:
- 传入参数处理不当,导致程序crash
- 类型溢出,导致数据读出和写入不一致
- 因对象权限未进行校验,可以访问其他用户敏感信息
- 状态处理不当,导致逻辑出现错乱
- 逻辑校验不完善,可利用漏洞获取非正当利益等
用例设计
前面说明什么是接口以及什么是接口测试,接下来详细看看如何才能更好的进行接口用例设计
一、参数校验
对于接口来说,输入就是入参。常见参数类型有:
- 数值型(int、long、float、double等)
- 字符串类型
- 数组或链表
- 结构体
1.1 数值型
数值型参数主要考虑的设计思路
1.1.1 等价类
- 取值范围内
- 取值范围外
1.1.2 边界值
- 取值范围边界(边界最小、最大、边界最小-1、边界最大+1等)
- 数据类型边界(如int类型数据最小、最大)
1.1.3 特殊值
- 0
- 负数
1.1.4 遍历法
- 取值范围的所有数值遍历
栗子
整型: 最大最小值限制、0和负数的限制
浮点型: 最大最小值限制、0和负数的限制、小数点后位数的限制
常见问题
- 特殊值处理不当导致程序异常退出
- 类型边界溢出
- 取值范围外值未返回正确的错误信息等
1.2 字符串型
字符串型的参数,主要考虑字符串的长度和内容
1.2.1 字符串长度
- 等价类(取值范围内、取值范围外)
- 边界值(规定范围边界、类型边界)
- 特殊值(0、空字符串)
1.2.2 字符串内容
- 特定类型(英文、中文、大小写等)
- 特殊字符(,.><=$&^%~"*等)
- 敏感字符("法轮功"等)
栗子
空串、空白符号、长度限制校验、中文、全角半角、特殊字符
常见问题
- 传入非特定类型程序异常退出
- 超长字符未进行处理,导致存储、显示等异常
- 其他用户可见设置的敏感字
1.3 数组或链表类型
参数类型为数组或链表时,主要考虑成员个数和成员内容
1.3.1 成员个数
- 等价类(取值范围内、取值范围外)
- 边界值(规定范围边界、个数边界值)
- 特殊值(0等)
1.3.2 成员内容
- 等价类(合法和非法成员)
- 重复法(重复成员)
常见问题
- 0个item时程序异常退出
- 重复的item处理时未去重导致结果异常等
1.4 结构体
结构体(struct)是一些元素的结合,元素实际也是数值型,字符串型,数组或链表
枚举类型
需要针对枚举类型进行具体的业务数据逻辑校验
对象类型
- 整个对象为null
- 对象不为null,里面某个成员为null
- 空集合
- 集合的最大size校验
1.5 其他问题
- 必传参数验证
- 参数值为null验证
二、功能逻辑校验
接口核心作用在于处理业务逻辑,针对功能逻辑的用例设计分析
2.1 约束条件分析
-
2.1.1 数值限制
等级限制、分数限制、次数限制、时间限制、数量限制、积分限制等 -
2.1.2 状态限制
登陆状态、签到状态等 -
2.1.3 关系限制
绑定关系、好友关系、授权关系等 -
2.1.4 权限限制
管理员、超级管理员等
约束条件用例设计的意义在于:
用户进行操作时,在该操作前端进行了约束条件的限制,故用户无法直接触发请求该接口,但如果前端有bug或者通过接口请求直接调用,那么针对这些条件限制十分重要
常见问题
- 约束条件判断不足,导致用户可通过特殊手段获取利益
2.2 操作对象分析
面向对象首先得有对象,业务处理逻辑也是针对对象的,例如用户线上授课,课件就是操作对象,而课件的元素、属性也是对象
常见问题
- 用户可访问非权限内的其他用户信息、敏感信息,从而利用这些信息谋取利益
2.3 状态转换分析
被测逻辑可以抽象成状态机,各个状态之间根据功能逻辑从一个状态切换到另一个状态
如果打乱对应的次序,从一个状态切换到另一个不在它下一状态集中的状态,那么可能出现逻辑问题
栗子
从某状态改变到新的状态,依赖特定的转换接口处理
对于某些转换接口,其输入状态是确定的(比如Fun23,这个函数只能把状态2转换为状态3,而不能把状态1转换为状态3)
测试点可以如下设计:
- 状态为状态2,调用接口Fun23(),状态切换到状态23
- 状态为1,3等,调用接口Fun23(),状态不能切换
常见问题
- 可通过特殊手段达到原本不能的状态,从而谋取利益
2.4 时序分析
在一些复杂的活动中,一个活动是由一系列动作按照指定顺序进行的,这些动作形成一个动作流,只有按照这个顺序依次执行,才能得到预期结果
在在接口测试时,需要考虑如果不按照时序执行,是否会出现问题
常见问题
- 非顺序执行后,数据出现异常,可能还会出现程序其他异常
- 通过打乱顺序获取利益
2.5 数据精度分析
在处理业务逻辑时,有时候因为数据精度问题导致出现计算
数据精度的校验考虑的数据
-
2.5.1 时间
秒/毫秒、时间戳 -
2.5.2 金额
两位小数、元/角/分
2.6 用户体验
接口属于模块之间的调用,有时候前端直接展示接口返回的信息
- 2.6.1 接口返回提示
接口返回错误提示是否合理&友好
三、异常校验
异常校验涉及服务内部异常、依赖的外部服务异常、依赖的中间件异常等等
3.1 依赖服务
依赖的下游服务调用异常思路
-
3.1.1 调用异常
依赖服务调用抛异常
返回失败(有明确返回失败信息、返回null、http没有返回body、部分成功部分失败)
返回不同状态码的处理 -
3.1.2 调用超时
下游服务调用超时 -
3.1.3 重试机制
服务调用重试机制(重试次数、间隔时长) -
3.1.4 调用校验
http url的正确性校验
入参的正确性&完整性校验(如分页信息,是否查了多余信息)
3.2 中间组件
-
3.2.1 抛异常
-
3.2.2 超时
3.3 循环内中断
辅助手段
需要针对服务及接口对应的依赖服务和中间件(nginx、redis、db、mq、kafka等等)进行梳理,不同情况下的模拟
- 访问超时和丢包可以使用linux的tc命令来设置
- 服务挂掉可以通过改ip或端口模拟
- 依赖第三方接口的异常返回码可以用mock模拟
四、数据校验
接口业务逻辑中关于数据的处理逻辑重中之重,接下来针对数据校验的几个方面来说明一些校验的维度
4.1 数据一致性
-
4.1.1 长度一致性
DB字段和代码定义类型的长度一致性
DB表字段定义是否合理
上下游系统相同字段的长度一致性
前后端长度一致性验证
批量接口入参的最大size限制要和需要调用的外部接口的最大size限制兼容 -
4.1.2 多数据源一致性
缓存和DB之间的数据一致性
4.2 幂等校验
4.3 事务验证
-
4.3.1 回滚操作
验证是不是所有写操作都回滚
重点验证回滚逻辑的正确性 -
4.3.2 数据源
验证有没有一个事务中出现使用两个数据源
9.3 读写分析验证
-
9.3.1 关注从库延迟
-
9.3.2 主从配置是否正确
五、场景反推校验
在设计功能用例时,仅限于接口文档或了解的信息进行用例设计,有时候需要增加一些辅助手段更好的深入测试
5.1 批量处理
- 5.1.1 sql过滤条件
通过sql语句的过滤条件去反推业务场景和开发要筛选的数据是否批量
5.2 重点关注字段
-
5.2.1 sql表字段状态
sql涉及的表中表示状态的字段 -
5.2.2 sql表字段删除状态
sql涉及的表中表示删除状态的字段
检查思路:过滤条件是否足够及该过滤的数据有没有被过滤,比如删除状态的数据要不要过滤、禁用状态的数据要不要过滤
六、日志检查
在接口测试时,不仅仅是关注功能是否能正常实现,还需要关注日志信息是否正确
6.1 必要性
有没有,需不需要
6.2 准确性
信息够不够,有没有多余
6.3 日志级别
日志级别对不对
6.4 日志设置
需不需要开关,开关开启机制
6.5 日志收集
是否异步收集,性能是否有影响
6.6 敏感性
日志中有没有包含敏感信息、用户信息
七、健壮性
调用链路(下游)的接口超时时间合理性
八、并发性能校验
在接口测试时,性能方面主要关注并发是否导致一些功能逻辑的问题及单个接口的响应时间
8.1 并发死锁
-
8.1.1 线程死锁
-
8.1.2 db死锁
8.2 接口响应时间
-
8.2.1 单接口响应时间
-
8.2.2 批量查询接口响应时间
-
8.2.3 批量处理接口响应时间
九、安全性验证
9.1 敏感信息
-
9.1.1 敏感信息不能暴露给用户
-
9.1.2 url或rsp中不能包含敏感信息
9.2 sql注入
十、sdk版本兼容性
如果依赖sdk,需要重点关注sdk新旧版本的兼容性