接口测试用例设计
2.1、接口参数基本校验
2.2、正常功能逻辑校验
2.2.1、入参处理
2.2.2、常用变量类型注意点
2.2.3、实际业务校验点
2.3、异常处理逻辑
2.4、日志检查
2.5、数据一致性
2.6、写接口相关
2.6.1、幂等校验
2.6.2、事务验证
2.7、性能并发问题
2.7.1、线程死锁
2.7.2、DB死锁
一、接口测试用例设计
2.1、接口参数基本校验
一个接口的入参,在不考虑具体的业务逻辑的情况下,我们大致需要注意以下两点:参数类型、参数是否必填。
参数类型:可以根据开发设计文档去查看代码中参数类型与接口文档是否一致。
必填参数校验:验证接口必填参数是否合理、必填参数未填写请求接口是否能正常处理(例如抛出异常等)。测试入参是否限制必传:白盒测试一般可以通过查看代码看字段是否添加相关注解用来限制必传,黑盒测试则通过调用接口来验证。
2.2、正常功能逻辑校验
关于正常功能逻辑的校验,就需要根据实际的业务逻辑,采用不同的用例设计方法,设计出不同的用例去校验代码是否符合预期。排除开具体的业务,在其中我们需要注意以下几点。
2.2.1、入参处理
在前面说到了对于接口参数的基础校验。在此基础上,一般还会在接口方法中,根据业务逻辑对入参进行判断或者处理。如下:
异常参数 :针对异常的参数,例如参数对象中指定字段为空,但业务场景下不能为空,从而需求进行判断,如果出现,则抛出异常或者其他处理。
参数正常处理:例如入参为一个商品编号的集合,在该接口A逻辑中需要调用接口B,但是调用B接口中,限制入参的商品集合最大长度为20,所以接口A需要在调用接口B的那块逻辑进行循环调用,需要对入参的商品编号进行特殊处理。
2.2.2、常用变量类型注意点
根据变量类型的不同,需要注意以下测试点:
字符串:注意变量为 null、空串、中文、全角、特殊字符,字符串长度是否限制等特殊情况。
//例如判断字符串是否为null或者空字符串,一般用下StringUtils工具类,防止出现空指针
public static void main(String[] args) {
String s=null;
System.out.println(StringUtils.isNotEmpty(null));
//System.out.println(s.isEmpty());
}
1
2
3
4
5
6
整形:最小最大值、0和负数的限制。
浮点型:最大最小值、0和负数限制、小数点后位数限制。
对象:对象为null、对象中字段为null、空集合。
布尔型:是boolean类型的话,注意默认值为false;是Boolean类的话,注意默认值为null,防止空指针。一般而言,都是建议使用Boolean类。
/*例如 PermittedParamVo类中定义Boolean类型的uniqueDepartment字段,
前面的逻辑中,只对指定情况下设置字段uniqueDepartment为true,但是没有不在情况内,
设置字段为false。导致后续进行如下判断,直接空指针*/
if (permittedParamVo.getUniqueDepartment()) {
//.......
}
//优化为如下
if (BooleanUtils.isTrue(permittedParamVo.getUniqueDepartment())) {
//.......
}
1
2
3
4
5
6
7
8
9
10
Json相关:Json格式字符串转换为JSON对象或者JavaBean。
//1.使用JSON.parseObject转换时,若字符串为空字符串,则会转换为null
public static void main(String[] args) {
//输出null
System.out.println(JSON.parseObject(""));
//输出{} 防止出现空的情况下,给定字符串为空字符串情况下的默认值
System.out.println(JSON.parseObject(StringUtils.defaultIfBlank("","{}")));
}
1
2
3
4
5
6
7
2.2.3、实际业务校验点
这部分而言,重点还是实际业务校验点的部分。我们需要根据实际的业务逻辑设计出对应的测试用例,从而验证到对应的功能。具体可以参考上一遍博文的几种用例设计方法去设计用例。软件测试之用例设计,入门必备!
2.3、异常处理逻辑
对于接口中出现的异常情况,一般分为调用外部接口异常和相关中间件的异常。而这其中我们需要注意以下问题。
外部接口抛异常:如果是外部接口抛出异常后,我们是否进行了捕获异常的处理,且需要考虑这里调用外部接口异常后,该接口后续的逻辑是否还需要正常处理。
外部接口超时:设置的超时时间是多少?多久没有返回就算超时?外部接口超时后如何处理?
返回失败:当返回失败中,有无对应的信息。是否根据错误信息进行对应的处理。如果外部接口返回null后我们如何处理,这些都是需要考虑到的。
重试机制:有的时候,因为调用外部接口超时或失败,会进行重试再调用接口,我们这里重试的次数会设定为多少?
相关组件异常:调用相关组件失败后,接口的逻辑应该如何处理,也是需要考虑的一点。
2.4、日志检查
是否需要日志:判断是否需要打印日志。
日志是否设置开关:是否是一直需要对应的日志,还是说该日志只是用来排查问题,不一定一直需要,从而考虑设置开关。
日志级别:打印日志的级别是否合理,是Error还是Warn,或是Info。
日志打印的信息:日志打印出来的信息够不够,或是多不多了。
敏感信息:打印的日志中是否包含敏感信息,例如订单号、用户信息等敏感信息一般都不允许在日志中打印出来。
2.5、数据一致性
DB字段类型和代码定义类型是否一致:以下图为例,是Mysql数据库字段类型和Java变量类型的一个对照表。需要注意的是,像删除状态is_deleted、启用状态state 代表状态的字段,在Java中用Boolean类型,但是在数据库中一般都是以tinyint类型的0、1来存储。
JDBC类型 Java Object类型
CHAR String
VARCHAR String
TEXT String
NUMERIC java.math.BigDecimal
Decimal java.math.BigDecimal
TINYINT Integer
INTEGER Integer
BITINT Long
DOUBLE Double
date java.sql.Date
time java.sql.Time
timestamp java.sql.Timestamp
上下游系统相同字段是否一致:注意上下游系统,对于使用到的同一个字段的处理是否一致,避免出现故障。例如下游系统B某个字段可以有特殊字符,但是上游系统A在处理这个字段的时候,没有考虑到这种特殊字符的情况,也可能导致相关问题。
缓存和DB的数据是否一致:对于使用到缓存的数据,要保证缓存中的数据与DB中的数据保持一致。保证DB与缓存数据一致性可以通过消息队列的形式,当有服务更新DB的时候,通过消息队列的形式异步去更新缓存。
2.6、写接口相关
2.6.1、幂等校验
幂等:是一个数学与计算机学概念,常见于抽象代数中。在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。
对于接口而言,幂等校验就是同一个接口,多次发起同一个请求(参数一致),必须保证对系统的影响是一致。一般而言,针对增删改操作的接口,幂等校验就是保证操作只执行一次。例如以下场景:
订单接口:同样的入参,不能多次创建订单。
支付接口:重复支付同一笔订单只扣一次钱。
普通表单提交接口: 因为网络超时等原因多次点击提交, 只能成功一次等等
2.6.2、事务验证
事务的概念:以A转账给B100元这个操作为例,实际是有两个步骤:1.A账户减少100元, 2.B账号增加100元。这两个步骤,要么全部执行成功,要么全部不执行,不能只执行其中一个步骤,从而就会将两个操作放在一个事务中。
BEGIN TRANSACTION //事务开始
SQL1
SQL2
COMMIT/ROLLBACK //事务提交或回滚
1
2
3
4
验证写操作是否能回滚 & 回滚逻辑是否正常:例如上面这个转账的例子,就可以有两个用例:正常流测试用例:执行第1个业务逻辑插入数据到第1张表成功,执行第2个业务逻辑成功的测试场景,校验两张表的数据都操作成功。异常流测试用例:执行第1个业务逻辑插入数据到第1张表成功,执行第2个业务逻辑失败的测试场景,校验测试结果的重点是第1张表的数据会回滚。
多数据源实现读写分离:如果开启了一个读写事务,那么必须使用写节点,如果是一个只读事务,那么可以使用读节点。
2.7、性能并发问题
一般而言,针对核心域的新增接口,在发布上线前都会根据业务场景的需求,进行性能测试,查看性能是否能达到预期。在电商行业中,一般在大促前,也会进行对应的性能演练,查看相关域是否需要优化代码或新增服务器等操作。
2.7.1、线程死锁
线程死锁:线程死锁就是有两个以上的线程,一个线程锁住了资源A,又想去锁定资源B,另外一个线程锁定了资源B,又想去锁定资源A,两个线程都想去得到对方的资源,而又不愿释放自己的资源,从而造成一种互相等待,无法执行的情况。具体参考如下博客:【性能测试】-- 线程死锁和阻塞
2.7.2、DB死锁
DB死锁:当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。 简单的说,进程A等待进程B释放他的资源,B又等待A释放他的资源,这样就互相等待就形成死锁。具体参考如下博客:数据库死锁分析与解决