PyUnit下的接口测试(一):组织测试用例

开篇

因为这一系列文章大部分基于实际工作中的经验,很多问题可能是因为“星海”(公司内部的接口测试平台)的限制导致的。所以后续文章提供的解决方案并非最优解,仅供参考。

测试用例的设计

分类

根据黑盒测试的经验,对于一个接口的测试用例设计,可以分为“正常逻辑”与“异常逻辑”两大类。

正常逻辑,即通过对接口提交一组正常的数据,验证正常情况下接口请求的过程和结果;异常逻辑,对应各种可能的参数取值和各种异常情况下接口返回值的验证。

异常逻辑可能要考虑的几种情况举例:

  • 请求参数,例如常见的timestamp,向前一天、向后一天(过期),float、int(类型)
  • HTTP Header,比如UA
  • HTTP method,GET、POST这些HTTP动词
  • HTTP Status Code,类似200、301、401、403、502
  • return code,这里特指服务器指定的一些错误码,放在HTTP Body中,可能是由JSON字符串解析出来的

所以,第一步,根据用例分类的概念,至少需要设计两个类:SimpleCase和OtherCase。

分层

如果用例的数量达到一定级别后,如果每一轮都跑一个完整的测试,那可能耗时就非常多。假如是接入了持续集成,如果遇到短时间内连续多次提交代码,整个任务队列就卡死在那里了,体验非常糟糕。所以,这里也要参考黑盒时候的经验,对用例做分层。

按优先级分层

对于单个接口的一系列测试用例,需要按照优先级分层。比如,上面提到的“正常逻辑”是最高优先级;“异常逻辑”中,一些比较重要的如各种可能参数的验证,可以定义为中级;对于一些出于安全考虑的,“重要但不紧急”的,比如HTTP method等,可以定义为优先级低。

实际情况的划分中,可以参考著名的“重要紧急理论”:

按模块分层

这块还是拿持续集成来举例,假如我提交的代码能知道具体影响到哪几个接口,那我只测改动的部分就能节省大量的时间和资源。

根据URI(URL)的概念,我们请求一个URL时,获取到的是该URL描述的对应资源。所以说,我们在本地也按照文件夹(对应的是python的Package概念)形式来组织多条case;对于一个路径下的多个资源,使用多个module(即.py文件);对于一个资源的多种情况,在同一个module中使用多个类(TestCase)。

这么说比较枯燥,看下面这个图吧:

这里包含了两个接口:https://weixiao.qq.com/notice-api/sendhttp://weixiao.qq.com/school-api/key-secret。如果整个项目都是对应的同一个域名,那可以把域名那一层文件夹省略。

这样设计,还因为大多数测试框架都有“用例发现”的逻辑,而这个逻辑也是基于文件夹/文件的。

代码复用

这块得单独拿出来说明一下。如果是没有星海的限制,我们正常来写一个接口的相关case,完全可以先设计一个正常逻辑——SimpleCase,这里面定义一些属性存放参数,定义一个通用的方法用于发送请求。然后其它异常逻辑,全部继承这个类即可。

但是因为星海限制了不能上传文件,所有代码都是靠web页面复制粘贴(module的名字其实是固定的)。如果有要复用的代码,必须放在action里供测试用例调用。当然也可以把正常逻辑这个类放在action里return,但是和我们前面的各种设计初衷相违背。所以到具体实现的时候,采取的方案是:

  • 单个接口的正常逻辑、异常逻辑公用的方法抽象出来作为action
  • 接口参数部分,分为共有参数和私有参数,分别通过环境变量(公共变量)和类的属性两种方式来解决。

这部分具体的解决方案,还会在后续文章中讨论,这里就不展开了。