前言
京东APP核心购物流程因其重要性,内部称之为黄金购物流程,公司各大业务事业部都有许多个性化诉求,每个版本承接的需求量很大。研发在保证需求完成数量的同时,还需要保证代码质量和持续提升开发效率,对于工具的应用就显得非常急迫。
iOS Mocker是我们部署的一套服务端接口Mock工具,主要用于业务开发过程解耦、测试数据保存和分享、客户端容错测试等场景。目前已完成搜索、商详、购物车等核心购物流程的接入,内部存储的数据基本覆盖了这些模块所有线上可能出现的接口返回场景,为各模块的版本迭代和代码重构提供了更全面的数据保障。
现状和痛点
开发过程客户端依赖服务端接口进行联调
在开发阶段,客户端和服务端同时进行需求开发,客户端在有些需求上可能需要等待服务端需求上线之后再进入开发,这种等待是不必要的,也增加了客户端后期的工作压力。
客户端更便捷的积累和获取验证数据
以搜索结果页的商品列表为例,由于商品种类繁多,特性差异巨大,列表页中给每个商品的展示区域虽然很小,但是却希望将每个商品的卖家、好评、促销等特征信息全面的呈现出来,所以每个商品占位仅有242像素高的cell上总共分出了9个区域。每个区域的展示根据服务端下发配置的不同,不同机型适配逻辑不同,组合成200多种不同的展示形态。手机品类的几种情况如下图:
由于cell有复用机制,在线上环境,cell中的每一种布局在理论上都有被回收复用到另一种布局的可能。那么,我们如何保证每一种布局之间相互复用都不会有问题?如何保证在某个区域新增加一种展示方案后,不会对相关区域造成不确定的影响?这种全面验证的主要难点在于特殊数据的积累上,需要一个工具来辅助客户端研发创建和积累这些特殊的验证数据。数据积累之后,客户端研发在代码重构和需求开发时能更方便更快速的进行验证。
客户端容错和健壮性测试
在生产环境,客户端做好接口容错处理是必须的。比如接口某字段下发为null时候,进行各种容器操作会导致Crash,或者可能会导致界面显示不能降级,所以容错和健壮性测试也是很关键的。
Mocker目标
去除开发阶段客户端对服务端进度的依赖,研发在Mocker服务器上编辑Json数据,开发时对应接口直接从Mocker服务器上拉取预先编译好的数据进行解析,完成后续开发和自测,无需在客户端添加额外的任何测试代码。
Mock数据全面覆盖客户端所有测试用例需要的接口数据,回归测试时或者代码重构之后,可以结合测试的代码覆盖率数据,保证完成了工程的全面验证。
有效改善研发和测试的沟通和工作效率,研发在需求提测时候会携带验证的Mock数据ID,测试在功能测试期间不需要依赖预发环境就可以进行测试;测试在发现问题向研发提出时候也会携带对应的Mock数据ID,方便研发快速定位问题。
为客户端健壮性测试和自动化测试提供数据源,灵活修改接口下发所有字段的数据结构和数据类型。做到在不修改工程任何代码的情况下,能够通过Mocker向客户端返回任何有可能的数据。
Mocker方案、架构图、流程图
具体流程如下图:
服务端
搭建Mock Server,研发测试人员可上传接口数据或者使用Json编辑器直接进行编辑,生成接口的返回数据和唯一ID。该条数据在保存时会添加相应的接口名、校验参数、团队和模块等信息,通过此ID可以访问编辑完成的该条数据。
客户端
客户端接入Mocker在网络层统一实现,可以保证Mocker覆盖到客户端的所有接口。并且添加一个可以快速弹出的配置界面,由研发测试人员指定当前需要Mock的接口和数据ID。
1. 客户端所有接口都应该在配置了Mock ID之后能够生效,不再访问预发或者线上环境。
2. 客户端同一时间可以对1个或多个接口进行mock,其他接口正常访问预发或者线上环境。
3. 在任何页面都可以随时配置需要Mock的接口以及Mock到Server上那条数据的ID。
4. Mocker相关代码只在客户端debug模式下触发,并且在release模式下不会造成影响。
在具体实现上通过监听摇手机事件来实现配置界面的弹出,当该处理和客户端其他UI事件冲突的时候,可以设置关闭Mocker的摇一摇监听。
另外通过hook系统 NSURLSessionConfiguration类的 protocolClasses方法,添加一个自定义的 NSURLProtocol的子类来拦截发起的网络请求。在拦截之后判断当前请求的接口名是否在Mock配置列表中存在,如果存在,就取消原始请求操作并重新发起向Mocker的请求来获取Mock数据。
最后,我们后续还计划将APP版本接口文档的编辑和维护也结合到Mocker Server上,并且扩展测试用例数据组的概念,在敏捷开发和自动化测试方面进行更多的探索。