如何用 Mock 提高开发效率

Annie  |  2017. 07. 09   |  阅读 1940 次
无线开发

本文依托于我们团队出品的 https://easy-mock.com 在线mock系统介绍一下 mock 在日常开发中所扮演的角色,介绍一下 mock 是如何影响开发效率的。

工作流程和 mock 理念

其实我们公司在很长一段时间内都是没有 mock 类似的服务的,甚至开发者自己也没有自己在用的 mock 服务。按照这种没有 mock 环节的开发形式,我们发展出了自己的一套开发流程,并且很长一段时间都固化在这个流程上,稍后我会详细介绍下,其实不能说我们这套流程有问题,所以后面我们引入 mock 的时候,我们整理了 N 个 mock 系统解决的问题和带来的便捷,但是大家却感知非常模糊,为什么呢,因为一个软件的开发过程本身就是个很漫长的过程,这其中优化了一小块流程的时候,大家最大的感知不是你解决了问题,而是你改变了习惯,这本身就是成本,所以大家会隐约觉得你不是在解决问题,而是引入了不必要的成本。

后来,我们组织了多次分享,为大家剖析 mock 在开发流程中的必要性,这是一点,另外一点非常积极的影响就是,大家的这种感知逼着我们架构组去把这个工具做的非常自动化和方便,尽量的减少流程改变带来的成本,减少系统操作上带来的学习成本,所以后来很短的一段时间,这个系统就发展出了很多颇具特色的功能,而这些功能正是 easy-mock 的强有力的优势。

刚才提到,我们团队之前的开发流程,这里可以和大家做个简单的分享。我们团队算是一个中型的创业团队,目前大概不到200名程序员,在没有 mock 之前,其实有两个阶段,首先是早期的混乱期,项目管理并没有一个统一的规范的流程的时候,这时候,通常是在本地代码里直接写死一些模拟数据来实现所谓的 mock,或者是像前端,在自己的静态资源服务环境中建一些静态文件来模仿接口数据(对于客户端开发就没这么好的事情了)。后来,团队变大,业务变得多起来,这时候如果没有一个规范的开发流程,很容易失控。所以,我们制定了一些规范的流程。大体描述起来是这样的(部分流程有出入,视实际情况而定):

  • 需求,可行性评估(Leader参与)。
  • 需求评审,通常是交互稿或者原型。
  • 交互或者设计评审,确认逻辑细节。
  • 开发给出排期,包括(接口定义/前端开发/联调/提测/测试时间)。
  • PM或架构师系统和架构分析产出。
  • 服务端设计数据库和接口,给出详细的接口定义(swagger)。
  • 接口评审,完成后部署开发服务器,前端可以直接按照swagger文档请求定义的接口,返回的是完全写死的假数据。
  • 前后端分别开发。
  • 联调,提测。
  • 测试,预发。
  • 运维发布线上,测试回归线上。

这个流程中较为特殊的部分,就是和 mock 相关的部分,在之前我们的流程中,被第7步替代了,我们采用的方式是,后端定义好接口后,需要在代码中定义好空的 controller ,内部直接 response 一个写死的 JSON 数据,然后接口评审后,将此服务部署到开发环境上,前端可以直接请求这些假的接口。

听上去,好像也是一个完美的流程,前端不需要再自己模拟数据了,至少有一个假的接口可以调用了。那相对于独立的 mock 服务来说有些什么问题呢?

后端定义的接口很容易满足不了界面的需求,这时候前端在开发 demo 的时候,发现问题需要反馈给服务端,服务端需要修改接口定义,然后重新部署服务。整个过程的沟通成本和服务重启的成本都比较高,而且服务经常重启(java的重启速度大家应该都懂的),前端的开发会受到严重影响,但是时间长了之后,可能大家已经感知不到这个效率的损耗有多大了,甚至可能很多开发还享受于这个时间的损耗(顺便抽根烟什么的)。

体验过这种开发流程之后,你会发现,联调这个本应该独立的开发流程基本贯穿到整个开发过程中去了,前后端之间没有明显的分界点,接口定义好了之后反正有问题前端反馈服务端修改就好了,大家就这样不断的发现问题,修改问题,然后服务端部分功能开发完成之后,会直接把一些真实的接口也部署到开发环境,于是就慢慢地有些接口替换为了真实业务逻辑,最后变成了一个边开发边调试的过程。但是站回独立 mock 情况下来看,你会发现在前后端开发的过程中,有一个明显的分界点是多么重要,首先对于开发本身很有必要,然后也会倒逼开发者遵守标准的规范,定义尽量完善的接口(定义过之后修改有成本),开发尽量完善的前后端代码,并在一个明确的时间点快速联动起来。

综合来说,就是:在demo开发过程中,前端需要确保自己的数据模拟环境自己闭环可控(模拟的数据可控,环境可控),并且前后端之间要有一个明显的分界点(强制规范开发流程,减少损耗)。

这大概是前端对于 mock 服务最强烈的诉求,那服务端对于 mock 有些什么需求呢?

不想在接口定义的时候手动填一堆假数据给前端用,mock 中可以根据 swagger 中定义的 dto 实体的属性的类型生成 对应的 mock 数据。

希望在引入 mock 之后,不会对服务端的流程有任何影响。事实上,在 easy-mock 中,服务端需要做的事情和之前没有发生任何变化,只是他们的接口需要定义的更严谨,在 swagger 注解做好了之后,部署一个环境,将 swagger 的文档地址发给运维,运维会自动在 easy-mock 中的公司项目中生成一个公共的 mock,无需服务端任何冗余的流程。

服务端可以尽情重启,或者换环境,换机器,对前端的开发不会产生任何影响。

深入用过 easy-mock 系统的同学应该可以发现,easy-mock 在这些方面做了很多努力。

easy-mock 介绍

上一节,我们主要介绍了一些工作流程和 mock 的一些基本理念的由来。这一节,我们介绍下 easy-mock 的具体使用。

业界其实有很多 mock 的工具,有些是在线的服务,有些是可以自己部署的服务,而有些则直接可以集成到项目代码中。例如最知名的阿里巴巴的RAP,事实上,这里不是想做个详细的对比,因为用过的人就知道 easy-mock 的功能和易用性秒杀 RAP,并且 RAP 最近服务很不稳定,感觉已经是弃坑的趋势。相对于一些本地自己编写 mock 数据的方法,在线集中式服务的好处,自动生成 mock 的便捷更是不必多说,下面我们就介绍一下 easy-mock 的一些特色。

从 swagger 自动生成 mock

自动生成 mock,是 easy-mock 很重要的功能,在对原有开发流程低侵入方面扮演了很重要的角色。在业务开发中,服务端保持原有流程,编写swagger注释,最终通过 easy-mock 一键生成一个完整的项目,并且定义有更新时可以一键更新(而且在我们公司是运维负责这个“一键生成”),客户端则无需编写 mock 接口,因为已经根据服务端定义的各种实体和接口自动生成了 mock 规则(而不只是写死的数据),整个开发流程被这个自动生成的功能串起来。

swagger 生成 mock,支持 1.0 和 2.0 的语法,支持集成到代码中的 swagger 和自己手工编写的 yaml 的 swagger 等。

具体的使用,可以见图中标注的位置的文档。

基于 mock.js 的语法,和强化特性(动态接口)

easy-mock 的语法完全基于 mock.js , mock.js 其实是脱胎于 RAP 的一款阿里巴巴某大神出品的一个模拟数据生成的 JS 库,功能非常全面,可以通过简单的语法模拟各类常见的数据。

easy-mock 在 mock.js 上做了一些扩展,例如:

动态接口。除了 mock.js 提供的简单的 Function 功能可以实现动态的逻辑判断之外,easy-mock 还在每个 mock 接口里注入了一些 express 的变量,例如 _req.header / _req.body / _req.query 等等,事实上 express 原来 req 上有的属性基本都可以调用,这样就可以写非常动态的 mock 接口了,可以根据 cookie,header,请求参数 判断输出不同的数据。

restful 。当设置一个 mock 的路径的时候,可以设置成 restful 的风格,例如: "/api/:id"。这是 express 中 restful 的 route 的写法,当有一个请求进来时,可以在 mock 语法中调用 _req.params.id 获取到对应的 restful 的参数。

例如:

{
  "code|1": [200, 500],
  "default": "jso",
  "id": function({ _req }) {
    return _req.params.id;
  }
}

项目管理和共享

简单的说,easy-mock 中的项目可以分 个人项目 和 团队项目,个人项目可以在项目级别邀请别人参与共享,而团队项目则可以在团队级别邀请别人参与,这样所有人都会共享这个团队中的所有项目。

以此为基础,可以方便的在团队中使用 easy-mock,在我们公司也是如此,内部的 easy-mock 中有一个预先建好的大搜车的团队,默认邀请了所有人,所以公司内的项目都可以直接共享。

其他有趣有用的点

easy-mock 还有很多不容易被感知到的功能,例如:

swagger 修改后的智能覆盖规则,如果有一个接口被修改,不会粗暴的覆盖用户的修改,而是会判断用户是否修改过,如果修改过,就不会覆盖,如果没有改,才会覆盖。

根据 swagger 生成前端的 class model,而且带有注释,细心的同学可以发现这个功能。

可以查看接口在 swagger 中定义的入参和出参,其实完全可以抛弃掉 swagger 本身的界面了。

其他有趣的功能,还待大家自己去发掘额。

其他一些 mock 的场景

最后分享一个问题,mock 除了在正常的开发流程中扮演不可或缺的角色之外,还能做些什么事情呢?

单元测试,开发在写单测的时候,不可能用一个不稳定的服务来调用接口,这时候需要模拟一些调用的话,就可以用 easy-mock ,这个场景其实很常用。

自动化测试,这里说的测试不是开发自己的单测,主要是指测试团队在做一些常规的自动化测试的时候,如果开发的接口还没有跑通,可以用 mock 先让测试脚本跑通,最后再对接到真正的接口上。

其他一些内部系统之间调用的 mock,甚至服务端之间的 mock,为此,easy-mock 未来可能会支持一些服务端的通讯协议。

结语

关于 easy-mock 的介绍就先到这里了,关于开发流程以及 easy-mock 的使用,大家有问题可以加 QQ 群咨询:595325417

感谢 Vue,Vue Server Render,ElementUI,mock.js 等开源项目,这也是 easy-mock 所使用的技术栈。

分享到

   
用心思考 (IBM用户体验指导)