接口测试用例覆盖组织设计

本文主要发散接口功能性用例设计,对性能和安全暂时不做发散。


接口测试用例覆盖组织设计

接口测试用例设计

一、接口测试概念

1.1接口测试是什么?

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。


1.2 为什么做接口测试?

  a) 如今的系统复杂度不断上升,传统的测试方法成本急剧增加且测试效率大幅下降,接口测试可以提供这种情况下的解决方案。

  b) 接口测试相对容易实现自动化持续集成,且相对UI自动化也比较稳定,可以减少人工回归测试人力成本与时间,缩短测试周期,支持后端快速发版需求。接口持续集成是为什么能低成本高收益的根源。

  c) 现在很多系统前后端架构是分离的,从安全层面来说:

   1、只依赖前端进行限制已经完全不能满足系统的安全要求(绕过前面实在太容易), 需要后端同样进行控制,在这种情况下就需要从接口层面进行验证。

   2、前后端传输、日志打印等信息是否加密传输也是需要验证的,特别是涉及到用户的隐私信息,如身份证,银行卡等。


二 、接口测试可发现缺陷类型

大家可参考脑图往下梳理,有什么样的用例就会对应发现一种缺陷类型。

主要分为了接口技术层面和接口业务层面。技术层面主要面向服务接口开发,相关后台管理接口开发人员。接口业务层面可以面向产品人员,后台设计人员,运营人员等业务需求人员。

2.1、接口技术层面

2.1.1、输入参数验证校验不全面。

如:

1、入参数据类型长度边界,范围边界。

2 、入参数据内容、成员内容,有效无效,合法非法。

3 、入参数据 特殊字符 敏感字符过滤。

4 、入参可否必选。


2.1.2、接口内部触发的服务相关逻辑问题。

如:

1 、接口约束条件不够。 数值限制、状态限制、关系限制、权限限制、时间限制等

2、 请求对象与返回对象,不符合业务规则限制,返回类型长度无限制。

3 、请求时序序列控制限制问题。

4 、被测对象(请求或返回)状态控制问题。


2.1.3、接口返回值内容不符合要求。

如:

1、 服务定义错误码、内容不当、处理不当、场景不当。

2 、超时控制逻辑。

2.1.4、接口功能安全性问题。

2.1.5、接口性能问题。

2.1.6、接口请求和wiki文档不一致。

2.1.7、接口地址变更导致不可用问题。


2.2、接口业务层面

2.2.1、接口返回内容不符合业务需求。

1、不满足前端展示需求。

2、不满足当前前端业务场景。

2.2.2、接口涉及的落地数据问题。

1、服务计算处理逻辑导致接口返回数据不正确。

2 、触发的服务计算逻辑后导致的落地数据不正确。

3、接口兼容性, 扩展性不足。


三、接口功能测试用例设计

如脑图所列

接口测试与功能测试类似,在功能性测试用例设计方法深入理解与用例架构中我提到了用例设计的本质就是找对测试对象、组合设计、等价边界数值设计的用例设计本质和夹板思想,类似的接口通常也是有输入输出的,输入就是我们常见的接口的入参,可看作是输出的有落数据库落地数据,接口返回响应内容体,Http状态响应码,服务封装的错误定义码等等等等。大家可以随意发挥只要按你的夹板和测试需求可以作为入和出即可。同时相关前端调用相关接口,接口会执行相关业务处理逻辑。

接口测试的用例设计,主要从输入、输出和接口内部处理逻辑三方面考虑:

1)针对输入,可按照入参参数类型进行设计;

2)针对接口内部处理,可按照业务处理逻辑和相关技术处理逻辑进行用例设计;

3)针对输出,可根据输出的结果进行分析设计。


3.1 针对输入设计

对于接口来说,输入就是入参。常见参数类型有:

(1)数值型(int,long,float,double等)

(2)字符串类型

(3)数组或链表

(4)结构体

结构体(struct)是一些元素的结合,元素实际也是数值型,字符串型,数组或链表。

下面详细说明数值型、字符串型、数组或链表三种参数类型用例设计。

3.1.1 数值型

数值型的参数主要考虑以下几个方面设计:

如果参数规定了值的范围,则需要考虑等价类取值范围内、取值范围外,取值的边界,如有需要,可能会遍历取值范围内的各个值。

例如检查权限的接口:TaskChecker.checkTask(int taskID) taskID的取值范围是1-35,那么设计时考虑:

  • 1-35范围内和范围外的值;
  • 1-35的边界:0,1,35,36;
  • 类型的特殊值:-1,0
  • 数据类型的边界值:int的最小值最大值;
  • 因为1-35代码的权限ID不同,可能需要遍历1-35的每个值。

常见问题和风险:

  • 特殊值处理不当导致程序异常退出;
  • 类型边界溢出
  • 取值范围外值未返回正确的错误信息等

3.1.2 字符串型

字符串型的参数,主要考虑字符串的长度和内容:

例如接口转换设置闹钟的接口DateUtil.getDayOfDDHH(String ddhh),用例可以考虑:

  • 长度为4位,比4位少,比4位多;
  • 边界值:String的最大长度;
  • 特殊值:空字符;
  • 字符串内容可考虑类型:数字,非数字;
  • 特殊字符。
  • 如果是输入用户输入且其他用户可见的内容,则还需要考虑敏感字是否被正常过滤。

可能出现的问题和风险:

  • 传入非特定类型程序异常退出
  • 超长字符未进行处理,导致存储、显示等异常
  • 其他用户可见设置的敏感字

3.1.3 数组或链表类型

参数类型为数组或链表时,用例可以考虑:

例如批量提交任务的接口submitTask(int[] taskID),参数用例设计考虑:

  • 正常取值:1-5个权限,范围外:6个权限;
  • 边界值:1-35的边界值,请求允许最大最小值;
  • 特殊值:0个;
  • 合法ID和不合法的;
  • 重复的ID等。

可能存在的问题和风险:

  • 0个item时程序异常退出;
  • 重复的item处理时未去重导致结果异常等。


3.2、针对接口内部处理逻辑设计

接口需要进行一些业务逻辑处理的,那么按逻辑设计用例可以从以下几个角度分析。

3.2.1 约束条件分析

(1)数值限制:分数限制、金币限制、等级限制等等。

例如:兑换Q币活动要求积分>50才可参与。

(2)状态限制:登录状态等。

例如:同步用户信息需要先登录账号。

(3)关系限制:绑定的关系,好友关系等。

例如:帮家人防骗功能只能查询绑定家人的来电信息。

(4)权限限制:管理员等。

约束条件的测试在功能测试中经常遇到,在接口测试中更为重要。它的意义在于:用户进行操作时,在该操作的前端可以已经进行了约束条件的限制,故用户无法直接触发请求该接口。但是实际上,如果有其他手段:例如UI有bug或者通过技术手段直接调用接口,那么接口是否针对这些条件进行了限制就尤为重要。

例如常见的例子:要兑换5Q币需要200积分,但是我积分不足,所以兑换按钮是灰色无法点击的状态:

正常用户是无法操作的,但是兑换其实是调后台的一个接口,如果绕过页面按钮的限制,直接调用后台接口兑换呢?是否可以兑换?预期当然是不能兑换的。因此积分这个数值限制就需要针对接口进行测试,并且非常重要。

其他约束条件类似:

  • 时间约束:22:00之前;
  • 数值约束:积分200;限量5个;
  • 状态约束:登录手机管家;
  • 等等约束条件类似。

常见的问题和风险:

  • 约束条件判断不足,导致用户可通过特殊手段获取利益

3.2.2 操作对象分析

操作通常是针对对象的,例如用户绑定电话号码,电话号码就是操作对象,而这个电话号码的话费、流量也是对象。

对象分析主要是针对合法和不合法对象进行操作。例如下述用例子:

  • 用户A查询电话P1话费:
  • 用户A查询电话P1流量;
  • 用户A查询电话P2话费;
  • 用户A查询电话P2流量。

后台的逻辑处理,如果一个电话已经被绑定过,从后台的角度是可以查询到该电话的话费和流量的。但是在用户侧,应该是A绑定了的电话,才能让A查询到该电话的话费。故类似对象的测试也必不可少。

常见的问题和风险:

  • 用户可访问非权限内的其他用户信息、敏感信息,从而利用这些信息谋取利益。

3.2.3 状态转换分析

被测逻辑可以抽象成状态机,各个状态之间根据功能逻辑从一个状态切换到另一个状态。如果我们打乱了这个次序,从一个状态切换到另一个不在它下一状态集中的状态,那么逻辑将会打乱,就会出现逻辑问题。

如上图所示,从某状态改变到新的状态,依赖于转换接口。而对于某转换接口,其输入状态是确定的,比如Fun23, 这个函数只能把状态2转换为状态3,而不能把状态1转换为状态3。那么测试点就可以是:

(1)状态为状态2,调用接口Fun23(),状态切换到状态23;

(2) 状态为1,3等,调用接口Fun23(),状态不能切换。

例如在做任务的时候,任务有三种状态:未领取,已领取未提交,已完成三种状态。

那么可以这样设计:

(1)正常的状态切换:未领取状态,领取任务后变为已领取状态;已领取满足任务条件提交后,变成已完成状态;完成后可以再次领取任务。

(2) 非正常的状态切换:未领取任务满足任务条件直接提交任务;已领取时再次领取任务等等。

常见的问题和风险:

可通过特殊手段达到原本不能的状态,从而谋取利益。

3.2.4 接口时序分析

在一些复杂的活动中,一个活动是由一系列动作按照指定顺序进行的,这些动作形成一个动作流,只有按照这个顺序依次执行,才能得到预期结果。

在正常的流程里,这些动作是根据程序调用依次进行的,并不会打乱,在接口测试时,需要考虑如果不安装时序执行,是否会出现问题。

例如,客户端数据同步是由客户端触发进行的,期间的同步用户无法干预。功能测试的时候可见的就是是否能正常进行同步,而进一步分析,同步流程实际涉及了一组动作:

从时序图可以看出,后台有3个接口:登陆获取用户ID,上报本地数据,上报本地冲突。三个接口需要依次调用执行,才能完成同步。那么在接口测试就可以考虑打乱上述接口的执行顺序去执行,会有怎样的结果,是否会出现异常。例如:获取用户ID后不上报本地数据而直接上报本地冲突。

常见的问题和风险:

  • 非顺序执行后,数据出现异常,可能还会出现程序其他异常
  • 通过打乱顺序获取利益


3.3 针对输出设计

针对输出设计其实是针对接口返回的结果进行分析。

3.3.1 针对输出结果

接口处理正确的结果可能只有一个,但是错误异常返回结果有很多情况很多值。如果知道返回结果有很多种,就可以针对不同结果设计用例。例如提交积分任务的时候我们通常能想到的是返回正确和错误,错误可能想到:无效任务,无效登录态,但是不一定能否完全覆盖所有错误码,而接口返回定义的返回码可以设计更多用例:

覆盖返回码也是用例设计的一种思路。

常见问题和风险:

(1)错误前端处理不足,导致前端异常;

(2)错误提示处理不当,导致用户看到晦涩的错误码;

(3)错误提示不当,导致用户不知道哪里出了问题,如何解决。

3.3.2 接口超时

接口正常情况下是有返回的,那么如果接口不返回呢?也就是说接口超时后的处理也是测试需要考虑的部分。如果超时处理不当,可能会引起以下问题:

(1)未进行超时处理,导致整个流程阻塞

(2)超时后又收到接口返回,导致逻辑出现错乱


3.4 其他测试设计

3.4.1 已废弃接口测试

已废弃协议,是指之前有定义,但是因为需求变更或其他原因,目前版本不用。这些接口虽然不再使用,但有可能代码并没有及时删除。如果利用技术手段调用这些接口,可能获取额外利益。

例如,任务之前有个清理任务,在一个版本需求里将清理任务替换为下载任务。在新版本客户端已不再调用完成清理任务的接口;但是如果该接口未关闭,用户就可以继续请求submitTask(int taskID)接口完成清理任务获得积分。

因此新版本在考虑兼容旧版本的同时,还应做好相关废弃接口的检查,避免用户获得额外利益。

3.4.2 接口设计合理性分析

接口定义是否合理可以从以下几个方面分析:

(1)接口字段是否冗余;

(2)接口是否冗余;

(3)接口是否返回了调用方期望得到的信息;

(4)接口定义是否可满足所有调用需求;

(5)接口定义调用是否方便。


本文综合参考了其他资料整理而来,只是做个梳理,希望大家继续不断优化各自公司内部的接口用例,做到一类用例对应一类接口缺陷类型,对接口问题缺陷类型进行不断深入挖掘,同时最好接口的缺陷分类和统计分析,有针对性的对某一接口用例进行强化设计,不断细化。

您可能还会对下面的文章感兴趣: