前言
在开始本文之前,需要声明以下关键词:
1.mock测试: mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。
2.restful: 一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
3.第一阶段: 项目开发分为三个阶段,即通俗解释的:需求评审阶段、开发编码阶段、验收阶段。而需求评审阶段对应第一阶段。以此类推。
4.接口测试: 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。在本文主要特指 “API测试”
5.API测试: API(Application Programming Interface,简称:API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。
6.API功能测试: API测试是针对系统所提供的API做各方面的验证。API的性能和安全测试根据测试策略的不同,会是一个可选测试项。这个可以作为两个单独的问题来讨论。API的功能测试类似于UI功能测试,都是在已知输入内容和期望结果的前提下,使用这个功能/调用这个API并且验证是否能返回期望的结果。不同的是API测试在返回结果被呈现给客户前就完成了,从而对测试环境的依赖会比较小。
7.ATMS:API Automatic Testing and Mocking System,接口双向服务系统。
一.背景分析
经过多次项目开发及对项目的测试工作,总结到我们公司乃至社会上的同类企业都存在以下问题:
1.对开发编码时期运行过程中的测试工作不足,出现该情况的主要问题在于两点:
(1)测试人员对开发技术不了解,多数无法穿插到开发编码时期进行一些对接型的测试。
(2)大多数企业的惯性思维,认为测试就应该是开发结束并成型后才引入。
2.测试所使用的工时过短,该情况出现原因如下:
(1)个别企业及开发团队有种“功能开发出来就好,测试等上线再做”的先斩后奏的意识,从而导致在项目周期中,测试的工时安排被推到特特别后,甚至仅仅在上线前做一次临上线的测试。从而带来了更多的隐患。
(2)个别企业及开发团队轻视测试,在测试方面的投入不足,甚至让开发自行进行测试。或者是把项目开发得七七八八的时候,交由测试跟测试说:“随便测试下就好了”
3.前端依赖后端开发,前端的进度很大程度上受到了后端的制约。在当下的技术氛围中,大多数是前端开发好页面后,对接后端的数据,对接方式分为两种:(1)后端渲染型,后端将前端页面放到后端模板引擎中进行渲染。(2)前端通过接口对后端交互数据,并在前端渲染。这两种都有对后端强依赖的特点,因为后端提供数据源,前端无法在不修改代码的情况下构造合法数据。
4.后端开发了接口一旦数量达到一定程度,检查的成本会变得越来越高。后端开发接口的过程中,当开发了第N+1个接口,需要保证前N个接口仍然运行正常,因此需要对前N个接口进行测试(API测试)。当已开发的接口达到一定程度,此时手工测试就是一个很痛苦的过程了。需要耗费大量的时间去测试过往开发的接口。
5.前端的请求中包含的数据的数据结构不一定是后端需要的数据结构。在前后端开发同步进行时,前端接入后端的数据,此时需要进行接口交互。前端的请求可能没有按照规则来,同样的也会导致后端无法接收到预期的数据而不能按预期运行。当发现此类问题后,需要耗费时间成本和交流成本去修正。
6.上线前后无法在短时间内将所有接口都测试一遍。项目上线前后都需要一次调试的过程,但是因为时间不足,普遍功能覆盖率不高,无法在短时间内将所有的接口都检查一遍(是否存在404,500等影响用户体验或者影响业务的情况)
7.日常做定期的接口全面覆盖测试的成本非常高。在项目上线后或者迭代频次降低的时期,测试人员可能已经在负责其他事务。这个时期容易出现以下问题:日常的全功能覆盖无人负责,即使有人负责成本也会非常高,突发状况出现的时候没有一个预警机制。
8.项目进行迭代或者持续集成之后,不能保证新功能是否会影响已有功能的运行。该问题同6
9.后端开发人员存在对测试依赖的情况,开发好的接口交给测试来测试。出现这个情况主要原因是开发任务重的时期,开发人员着重开发接口不愿意去自己进行测试。从而导致测试人员的工作量抬高。
综上分析,我们公司及同类企业需要将开发阶段的测试工作重视起来,而同时需要满足以下要求:
1.对测试人员的技术门槛要求不能太高,也不能耗费太多的成本聘请太多精通开发的测试人员。
2.测试的过程尽量傻瓜化,尽可能降低测试的用例录入成本。
3.能够有一个自动化的平台,通过自动化平台对项目进行批量自动化测试,并生成报告(网页报告、邮件报告等)
4.自动化平台能够活对接持续集成或者其他形式的平台,通过一个特定的请求发起测试,并获得测试结果。
5.平台能够对前端的请求进行测试,保证前端请求按照要求的发送。
6.平台能够在前端请求通过的情况下,给前端发送虚构的合法的数据。使前端脱离后端依赖。
7.测试用例能够用一种灵活的方式实现数据库存取。
8.测试结果能够存储数据库,并能够进行各方面统计。
二.demo设计及开发
针对上文所提出的问题,在本文编写之前开发了几套demo,每个demo都经过了真实项目的运作,并获得了宝贵的经验。
demo总共存在三代版本的五套系统:
第一代版本测试自动化引擎:基于mocha.js+supertest.js的接口批量执行工具。
该版本的自动化测试引擎的性质是工具,解决了以下问题:
1.解决了对特定项目的接口批量测试的问题,能够针对每个接口录入特定的测试用例并批量执行。
2.解决了友好反馈的问题。该引擎测试完成后,生成.html文件格式的测试报告。
3.采用语义化程度高的断言库,例如data.should.be.equal(10),代表:data必须等于10
同时该版本也存在以下问题:
1.未能实现平台化,需要执行测试的人员在本机安装对应要求的开发环境,并且不是每个终端都能够正常运行该引擎。
2.测试用例维护成本高,需要维护测试用例的人员具有一定程度的js语言基础,且测试用例代码编写繁杂。
3.多终端测试用例不同步,甚至需要采用git来进行同步。因为测试用例是采用文件流的形式存放,导致必须采用文件流的协同方式来维护各个终端的测试用例。
4.测试出现错误没有合理的预警机制。没有类似邮件警报的形式对测试系统的错误进行实时汇报,仅仅只是html文件呈现当前测试结果。
5.测试报告不够灵活,不能实现对不同的情况的统计。例如:xx接口测试共出现xx次错误,错误率xx%。
第一代mock服务工具:基于mock.js+kraken.js的接口数据模拟工具
该版本的mock生成工具属于半平台半工具的性质,采用kraken(nodejs)作为接口服务的模拟器,维护方式为文件流。前端开发者只需要对其进行发送特定路径(事先拟定的)请求,即可获取到所需要的模拟数据。其解决了以下问题:
1.使前端开发能够大部分脱离后端进行开发,解决了前后端开发强依赖问题。
2.当出现接口改动的时候,mock能够相对起到一个缓冲的作用,前后端通过mock来快速同步修改。例如:需求中要求多加一个share字段,前后端商量完毕后,先行在mock服务上修改,之后前后端开发人员即可分头进行开发,改变了以往开发需要等待后端开发完毕后再交由前端进行对接,节约了交流成本,降低了滞后的风险。
同时也存在以下问题:
1.前端可以对对应路径的mock接口随意发送数据既可以获取到所需要的数据,此处忽略了对前端的限制,前端对接口的请求数据不合法的情况下没有做拦截,导致接入测试时前后端对接失效,增加了返工的时间。
2.个别比较需要控制的数据在mock中无法直接控制(mock的数据是定向随机数据),例如status这个字段的值有多个情况,而前端开发者可能只需要其中一种,可能需要重复请求非常多次才能获取到需要的数据,增加了开发的时间。
3.mock给出的数据中错误码是恒等于正常错误码的,因此需要异常错误码的场景无法mock。
4.维护方式为文件流,导致每次有新的接口需要同步到服务端都要git进行协同,维护的成本变得非常高。
第二代自动化测试服务:mocha.js+supertest.js+kraken.js+vue.js
这个版本的自动化测试同样也属于半工具半服务的性质,维护方式同样是以文件流的形式,解决了上一代版本的以下问题:
1.该版本解决了上一代未能实现平台化的问题,采用了一个kraken服务打造的中间服务层,vue构造的控制台向服务发送指令即可调用第一代为基础的测试机进行测试。
2.通过封装的shell脚本和js代码,实现了输入多条指令即可批量构造测试用例。
3.测试用例和断言实现了傻瓜化,实现一条简单语法的测试用例即可检查多项检查点。解决了对测试用例维护人员的门槛问题。
同时也发现了以下问题:
1.该版本的测试报告属于一次性报告,下次测试将会把上次测试的记录抹除,无法回看。
2.测试用例同步问题未解决,依然需要使用git进行协同。
3.缺乏提醒及警报机制,出现问题只有一个html文档。
4.维护麻烦,每次有新项目必须要新建一个目录进行维护。
第二代mock服务工具:adonis+mock.js:
该版本为过渡版本,系统底层从kraken转向adonis,并增加了部分功能。解决了如下问题:
1.增加了post校验工具,前端发送的请求必须通过校验(事先设置)才能够获取到mock数据。
2.增加了数据控制方法,能够控制需要控制的数据,可直接更改请求返回中的值。
第三代接口双向服务平台(ATMS):adonis+supertest+mysql
这个版本解决了上面大部分问题,且为以后打下了一个平台的基础,具有良好的可拓展性,以后的迭代可以直接在本版本中进行优化而不是换代。解决了如下问题:
1.通过mysql进行数据维护,测试用例及接口信息可通过数据库进行存取,解决了平台性瓶颈问题。
2.优化了测试用例的录制方法,测试用例录制更简单。
3.增加了构造表单的功能,可对需要测试的接口进行表单构造(mock),可生成任意结构,任意长度的表单数据并测试。
4.mock和自动化测试合并,一个测试用例可同时维护mock和自动化测试,实现双向服务。
5.继承了前代的所有特性,并增加了测试报告回看功能。
6.测试报告可邮件分发。
7.增加了单点调试工具,可单独对一个接口进行测试。
8.可按项目为单位进行批量测试。
三.同类产品分析
本文编写之前,对以下几款同类产品进行了一些分析:
Postman: 一款非常经典的接口调试工具,其带有一定的测试自动化功能,且有非常强大的可模拟所有环境的终端,甚至可以无视跨域。
其有以下优势可以进行借鉴:
1.可自由配置headers,可以请求更复杂的接口。
2.可配置切换环境,可以多个环境进行切换,例如:由开发环境切换到生产环境进行回归测试。
3.可配置的接口测试脚本,可以测试更复杂的接口数据。
同时我们产品也有比其优越的点:
1.postman的本质是个工具,同样的缺乏用例一致性的问题,数据同步问题我们产品已经解决。
2.自动化测试配置难,需要一个个用例写js代码,这个问题类似我们产品的二代版本,当前已解决。
3.功能仅仅只能做接口调试,不能像我们产品的mock那样为前端进行服务。
4.测试记录不保存。postman底层是文件流,并无数据库存储,因此测试报告不能保存。
RAP:由阿里巴巴开发的接口mock工具。
我们产品的mock服务部分参照该产品进行开发,它有很不错的项目管理机制:
它的接口管理功能比较复杂,mock的语法可读性不高,录入的成本相对我们产品要高很多。
它不具有接口自动化测试的功能,同时也不具有单接口调试的功能。
RAP具有以下优势可供我们进行参考:
1.用例录入可以以表单的形式进行录入,但是不宜太过于复杂,维护性很低。
2.导入功能,可以降低用例录入成本。
3.导出功能,编写文档时可以用于辅助。
贝塔猫:一个相对成熟的自动API测试平台
它可以按照项目进行批量测试,并发送邮件。
可以绘制项目的缺陷图表,用于统计。
可切换测试环境,进行多环境测试。
测试报告具有回看功能。
具有以下优点可供我们借鉴:
1.可对每个测试报告单独设置邮件发送地址(我们平台采用的是对管理员进行发送。)
2.图表统计功能,我们目前只有数据统计,暂无图表统计。
3.测试接口录入中,录入数据比较自由,类似postman。
4.具有可切换环境的功能,类似postman。
5.请求的数据结构的录入难度比较小,可参考表单录入的方式。
同时具有以下问题:
1.不具有先置条件(有些接口需要登录)
2.用例的的延展性不高,例如:有些接口可能有字段的数据不能被限制,或者要求限制必须为某个数据类型。
3.不能构造表单,如果表单复杂或者长度非常大,需要一条条进行录入。
4.不具有mock的服务,不能对前端进行服务及控制。
5.测试报告不稳定,有时候测试报告是一片空白(服务的bug),且测试报告的信息不够友好。例如:不能准确且友好提示错误信息。我们平台这点做足了。
6.邮件服务至今未发邮件过来,我们平台的邮件服务在测试完毕后立即发送。
7.不能为持续集成做拓展,我们平台做了预留,可通过一条请求让平台自动测试并发送反馈邮件。(定时测试也不是问题)
四.ATMS的优化方向
经过以上分析,ATMS仍有以下问题需要进行优化:
1.可录入多个环境,项目通过环境进行切换,解决多环境回归测试问题。
2.header可配置化。实现复杂接口的测试。
3.开发一个可供用例录入、报告查看、历史查询、系统配置的控制台。
4.第三方测试发起功能,实现一个请求即可发起一个批量测试,并发送邮件或者其他形式的反馈。实现后可活接持续集成方案。
5.缺陷统计,实现基于多个维度的统计功能(例:基于接口统计某接口的测试记录、错误记录等。)
6.mock服务需要实现函数级别配置化,能够实现使用函数生成更复杂的和更定制化的mock数据,提高前端的运用效率。
7.定时测试配置,可控制周期测试,并发送测试反馈。
8.拓展:在项目的模型下,再增加一个模块的模型,可通过模块进行批量测试。
9.拓展:mock服务可进行数据代理,前端可通过mock服务要求获取的是mock数据还是真实数据,如果获取真实数据,mock服务向真实服务进行一次被动测试,测试成功则返回真实数据,测试失败则反馈。该功能考察中。
10.管理员分组。
11.拓展:设计复杂测试逻辑的录入方式,在基本测试之外增加自定义测试条件。该功能考察中(安全性问题)
12.拓展:后期接入微信企业号,在微信端发起测试,查看报表等功能。
13.拓展:爬虫,可开发爬虫对后端渲染的页面进行抓取、检查。