2016.07.08 丨 壹佰案例

接口自动化测试框架落地实践

2016.07.08 丨 壹佰案例

黄伟东  

沪江教育科技  移动测试专家

3年无线测试研发经验,热衷于移动方向的自动化、专项测试、接口自动化测试技术钻研,在质量保障的基础建设上,有着比较丰富的经验积累。目前就职于沪江教育科技,担任无线测试研发工程师,独立负责无线端测试研发工作的开展以及平台建设。

本期微课堂,黄伟东老师跟大家聊聊接口自动化框架落地实践。




课堂实录


一.接口自动化测试


在聊接口自动化框架的设计之前,我们先来简单说说接口测试相关的知识。


接口测试跟普通功能测试一样,接口其实也是一个程序,所以对接口的测试思路,也跟测试普通程序的思路是一样的。只不过它并不像我们常见的Web、App程序那样,是有着可操作的GUI界面可以直接进行交互。


接口测试是数据输入与数据输出校验的一个过程,所以最直接的理解就是,我要测试一个接口,那我就要准备好这个接口相关的数据,进行输入,然后得到该接口的响应返回,并对返回进行校验。


这一个过程,其实跟我们做手工测试是一样的,可以不需要任何编码,通过基本的工具,如Postman、fiddler就可以完成。在Mac上替代Fiddler的还有Charles,这两款即是抓包工具,也可以用来做接口调试的工具。



而接口自动化的相关工作,无非就是将这么一个过程进行自动化,减轻人工的输入、输出校验工作量。


二.关于手工测试无法做到的难题


目前互联网公司中,一般分为三种类型居多,第一种是以硬件产品为主的公司,第二种是以Web产品为主的公司,第三种是以App产品为主的公司。特别是近几年中,第三种公司占主绝大部分。(当然,很多公司还是第二类和第三类的结合体)

我们今天主要来讨论一下关于以App产品为主的团队,App端的产品,跟Web产品最大的区别在于,App前端一般只负责用户交互逻辑,业务逻辑都会放到后端接口来进行处理。

特别是类似于电商类App、媒体类App,往往会是瘦客户端+胖后端的模式。

App产品为主的项目,其迭代速度也是短的,基本上都会处于1~2周小sprint,2~3周大sprint的节奏。所以这类团队的测试来说,接口质量直接反应着App的质量,做好接口测试尤为重要。


所以如果仅仅只有手工测试的话,往往会有如下一些问题:

1、接口随业务变化快,手工从GUI或抓包工具去验证,成本高;

2、异常数据的难以校验,从GUI层面需要花大量的时间去模拟环境;

3、接口请求正常,但是数据结构发生了变化,以至于发生的问题无法得到及时的排查解决;

4、线上出现问题,无法快速准确定位到是哪个接口出现了问题;


所以如果说你们也有这种情况的话,那你就需要一个能解决以上问题的自动化工具了。


针对以上问题,我们想象中的自动化工具应该是有如下功能的:

1、  能够替代手工,自动请求实现的接口测试用例,完成业务确认;

2、  能够自动校验返回的结果是否正确,最好能够校验返回的数据的结构准确性;

3、  能够在线上巡检,及时发现问题并且报警;


想象了一下,其实要解决的问题并不会太多,但是到底如何入手呢?


三.所以今天的重点就是,如何设计一个能解决以上问题的框架?


我们常见的接口测试,一般无非对Http或Webservice两种协议下的测试。那么我们拿最常见的Http来说。


对Http有了解的同学都知道,Http最常见有两种请求方式:GET/POST,无论是GET还是POST,我们都需要关注我们的输入,输入包括了headers、params、body(一般是post才用),这些都是我们需要准备的“测试数据”,一般情况下,请求完成后返回的数据都是json格式(不排除还有在使用xml格式的)。所以我们的一个业务接口的功能,就是在这一来一回的动作中完成。     


所以我们自动化关注的重点和设计思路主要有以下几个:




测试框架重点第一部分——基础方法支持(util):


a. Http请求相关方法,比如Get、Post、Put、Delete方法都需要提供比较友好的方法调用;

b. 数据格式处理与解析方法,在得到了response以后,我们需要对得到的数据进行过滤解析,使我们能够准确得到想要的字段以及该字段的值。一般情况下,常指的数据解析就是对于Json的解析工作;

c. 时间计算、随机数生成、md加解密等通用性方法,这类方法往往是用于帮助我们做些日常数据准备、数据加解密等的通用操作;


这三类,分别也包含了跟业务逻辑相关的基础方法、以及跟业务逻辑无关的基础方法。一般我们可以这么分类。




框架重点第二部分—— 测试环境与数据管理:

测试环境与数据管理这一块,是做接口自动化框架设计时需要特别关注的重点。


a.   测试环境隔离

一套接口,一般会部署在四套环境下面:开发环境、测试环境(部分团队与开发共用)、预发布环境、线上环境。

正常情况下,线上环境与测试环境所使用的数据库也是不一样的,那么这样带来的后果就是一套测试数据无法在多个环境共用。所以我们需要做好测试数据的配置,来隔离不同的环境,以保证编写的测试用例是能够覆盖多个测试环境的。


b.    测试数据准备与清洗

一个复杂业务接口的请求,有可能会改变某些业务的状态,导致某些场景在执行用例前后会出现差异,使下一次运行或对线上用户造成了影响。那么在我们用例的执行前后,我们需要对数据进行准备,并且在接口请求完毕后,要尽量对环境进行还原,以保证我们的测试没有残留数据,给业务或用户带来影响。


框架重点第三部分—— 用例执行策略和日志系统

Bvt用例与全用例的执行区分,错误重试等框架性行为必不可少。这个是从我们用例的执行角度出发,保证我们用例执行的稳定性和准确性。

以及框架内最重要的模块之一:log,也是在我们进行调试或者排错中起到非常大的作用。


框架重点第四部分—— 直观有效的report

直观有效的report是非常非常有必要的,因为接口自动化所运行的结果,不仅仅是给你自己看,也是给开发,甚至给产品关注的。所以你的报告是否能够直接明了得反馈出是哪一个业务出了问题,哪个业务的哪个接口报了异常,这个异常是因为网络问题还是因为脚本本身的问题?出错的具体原因是什么? 


这些都是需要我们在report部分需要做好的,不然的话,只有你看得懂的report,是很难被开发重视和认可起来。


四.具体方案推荐

那么基于以上重点,我们就可以开展我们的框架搭建了。


我们可以选择的方案其实很多,这里我推荐三个最常见的方案:

1、  基于Python:Nose(unittest)+Requests

2、  基于Python:RobotFramework+Lib

3、  基于Java:Testng+httpLib


这边我基于第一套方案来给大家做个介绍。




Nose继承自Python自带的unitest,非常易于使用。优点很多。

它本身也是一个command line tool,非常易于进行持续集成。


选用它的原因也简单,它自带的插件能够解决我们刚才所提到的框架中需要解决的几个重点:


1、  测试环境、数据隔离(通过nose-config插件)

2、有效的report报告,nose在执行完测试用例后,可以生成一个xml的报告,这个报告包含了执行每一个测试用例时的细节,包括执行时间等等,易于我们后续的错误分析。


除了Nose本身的好处以外,基于Python+Nose的模式下,我们可以定制复杂交互的测试用例,维护成本也相对较低,通过Jenkins来计划任务,日常自动化巡检也变得非常容易。




整个测试框架分别由三个层面组成:

1、  基础方法,这边就不赘述了

2、  逻辑层,这一层会对每一个接口进行独立的封装,封装内容包括了该接口的请求过程以及返回的数据解析,并且会对基本的返回结果进行校验。

3、  业务层,业务层指的就是我们的测试用例层,这部分用于组织业务的测试数据,并且通过调用逻辑层的接口,来组织单个或多个业务接口形成一个完整的测试业务流。

4、  逻辑层和业务层之间通过环境配置和数据的管理,来实现环境差异化。




以上基本是整个测试框架所关注的重点以及其基本构成,再谈谈接口测试和自动化脚本编写的介入时间。


在后端开发完成了接口开发以后,一般后端会与App端进行联调,联调完毕以后才会一起提交测试。


但是我比较建议接口先行提测,也就是说,当后端开发完,并且自测完毕以后,就可以把接口进行提交测试了。在这种情况下,测试更早接触直接跟业务相关的接口,并且能够在更早的时候发现了接口业务上存着的问题。


不需要真正到测App本身的时候,再去排查是API还是App本身逻辑的问题。如果时间充裕,可以同时把自动化脚本完成了,那这样的话,在App端提测时,我们的接口已经在自动化巡检了,这样也是极大地减少了App端的打回率和回归测试次数,App的问题都会提前得到暴露。




Q&A


Q:请问问接口测试的时候,数据库的验证写在case里?还是单独验证?


A:这一块的话,其实我是建议将数据库验证的逻辑,也是封装到逻辑层,在用例组织的时候,对有需要校验的业务,再进行数据库check。单独验证毕竟脱离了这个业务脚本,所以接口操作完毕后,马上校验数据库,也是一个不错的做法。


Q:一个复杂业务接口的请求,有可能会改变某些业务的状态,导致某些场景在执行用例前后会出现差异,使下一次运行或对线上用户造成了影响。那么在我们用例的执行前后,我们需要对数据进行准备,并且在接口请求完毕后,要尽量对环境进行还原,以保证我们的测试没有残留数据,给业务或用户带来影响。这一点具体的方案一般怎么做?


A:这一块的话,其实无非分两种方式:

第一种,从业务的方式去清理数据。比如,一个用例通过一个支付的接口购买了一个课程,这接口直接导致我们的购买的用户数据被污染了,用户会多出一个(购买过)的属性。那么我们就需要在用例结束后,可以调用删除购买的接口,来使该用户的(购买过)属性去除。这是一种通过业务控制的方式,在用例组织的时候,就可以开始把这一步思考到。


第二种就是做整个环境的初始化。在用例执行前,将环境进行初始化,用例执行完毕后,再次将环境还原初始化。  那么这个初始化动作呢,可以是整个系统的还原,也可以是部分程序或者数据的还原。  毕竟有代表性的工具可以参考一下docker的使用。


END



媒体联系

票务咨询:赵丹丹 15802217295

赞助咨询:郭艳慧 13043218801

媒体支持:景    怡 13920859305

提交需求