前言
随着移动互联网的迅速普及,手机淘宝业务在迅速的成长,目前已经发展成为拥有 40 多个 bundle(业务模块)的超大 APP 产品,在这后面有着数百名的研发人员的努力工作。业务的成长和人员的倍增给技术架构、团队合作、产品的交付都带来了巨大的挑战。本文将会讲述手机淘宝研发团队在两年的时间为了达到高质量持续交付的目标而做出的种种努力。希望借此机会向大家分享手淘的经验与教训,与大家共同探讨高质量持续交付之道。
第一阶段:单工程单构建产物、初级流程、初级质量保障
回到两年多以前,手淘还是一个年轻的产品,业务不多、研发人数不多、代码数量也不多、测试的手段也很单一。这个时期的特点就是所有代码都在一个工程里面,测试、发布都是围绕这一个工程的代码分支所编译出来的包来进行的。
工程架构
这个时候的手淘基本上就是一个大工程,依赖以源码依赖为主,所有的开发人员共享这一个工程,在同一个工程上开发。
存在的问题
- 代码混在一起,不便于管理。一个模块的代码有问题就会影响整个项目的开发人员。
- 不能支持业务的快速增长。
研发流程
工程的架构决定了研发交付的流程,所以当时的流程也比较简单,开发人员在本地开发完成以后直接提交代码,然后编译服务器进行打包,出包以后测试人员进行测试,如此反复,最根据代码库的最后一次提交进行发布。如下图所示:
存在的问题
- 提测和集成阶段混在一起,提测代码质量较差,开发人员不断的提交修改 bug 从而导致不断的集成包。
- 任何一个编译不过的问题会造成整个团队在等待。
- 回滚只能做到代码级别的回滚。
- 发布前回归如发现问题只能等待开发人员修改 bug,然后重新出包,再进行一轮回归,如此反复工作量很大。
- 如遇到阻塞问题,比如登录有问题,那么所有的人员都要等待登录的开发人员修改完 bug 才能继续工作,造成了大量的等待时间。
- 发布过程只有正式发布这一个步骤,很容易造成故障遗漏到线上。
质量保证手段
这个时期的手淘测试主要以手工测试为主,附加一些 monkey 测试和少量的自动化脚本。
存在的问题
- 纯手工的测试造成了测试人员大量的在做重复工作的现象。
- 测试经验没有积累。
- 非功能性的问题缺乏测试手段。
- 出集成包的节奏不可控,导致测试人员频繁换包测试,造成大量的重复工作。
- 对于不同的环境需要打出多种不同配置的测试包(如:测试包、预发包、线上包等),测试人员需要安装多个包进行反复的回归。
第二阶段:多工程单一构建产物、平台建立、初级持续集成、发布流程建立
随着移动互联网的迅猛发展,手机淘宝的业务随之倍增,研发人员也倍增。这个时候大小业务模块已经超过 20 个,研发人员超过了百人。这个时候原有的工程架构已经完全不能满足业务的需要了,质量保障也面临着很大的挑战,也就是在这个时期我们建立了一系列的平台:打包平台、发布平台、测试平台、验收平台从而使用自动化的方式提升了些效率。并且建立了灰度发布的流程,提升了最终发布的质量。不过这些努力也没有阻止质量和交付问题的大规模爆发……
工程架构
工程架构是整个研发的基础,所有的事情还是要从工程架构讲起。为了能够接入越来越多的业务,手机淘宝的架构从之前的单一工程的方式演进为模块化开发的方式,每一个模块被称作 bundle。同时引入了仓库的概念,每个模块将源码打包之后 deploy 进入仓库,然后由 builder 工程进行依赖管理并编译打包。
存在的问题
这次改造解决了之前多业务并行开发的问题,最终打包的时候也不会直接依赖各个 bundle 的代码库,完成了部分的解耦。但是还是存在很多的问题:
- 在同一个版本中所有的研发人员还是用的同一套依赖配置,任何模块的改动还是会影响其它模块,尤其是核心业务和框架层 SDK 的提交有问题的话会影响整个团队的进度。
- 仓库的版本管理混乱,开发和集成共用同一套仓库,开发可以随意部署,造成集成包无法控制。
- 由于各个 bundle 是将源码部署到仓库的,所以构建还是以源码为基础的,在代码越来越多的情况下,造成了整包编译速度缓慢。尤其是在等待很长时间以后编译失败,这种感觉是让人抓狂的。这个问题已经极大地影响到了研发的效率。
- 各个 bundle 的代码最终还是要编译到一个产物当中,各个 bundle 还是会相互影响,编译失败后定位问题成为了一大难题。
这里讲一下当时几个典型场景:
- 开发人员只是添加了一个方法,然后等待了 10 分钟进行编译,结果编译失败,然后排查一下午问题,结果是框架 SDK 更新导致的。
- 一大早几十个测试人员在等待回归验证发布包,结果发布包不是编译失败就是核心功能不可用最后到了凌晨 2 点钟,发布包终于出来了。
这样的场景太美,让人不敢去回忆。
研发流程
由于架构改造,提交集成的角色从开发人员变成了业务模块的研发团队,提交集成的方式从提交代码变成了 deploy 到仓库,但是由于工程架构的问题本质上没有完成各个 bundle 的解耦,所以整个团队还是在一条线上进行开发。不过这各阶段加入灰度发布的概念,灰度制度的建立使很多问题提前暴露,从而提高了正式发布版本的质量。
另外这个阶段建立起了代码审核、打包平台、发布平台、测试平台、舆情监控平台等,自动化了很多事情,在一定程度上提升了工作效率,大致使用流程如下:
存在的问题
- 集成的虽有雏形但依然不明显,提测和集成的界限依然模糊,很多 bundle 还是开发完以后直接 deploy 到主项目中然后打出集成包进行测试。
- 集成的标准虽然提出,但不能很好的运作,导致集成质量很差。
- 核心功能阻塞的问题越来越突出,长时间出不了可用的包成了一个大问题。
- 回滚操作依然困难。
- 项目的节奏依然混乱,导致项目延期和研发人员效率下降。
质量保证手段
这个时期的手淘测试团队建立了内存、性能、流量电量等专项测试机制,编写了一些半自动化的测试工具,建立了自动化适配平台,并组建了外包团队以提高测试覆盖率。这时候测试人员工作流程如下图:
存在的问题
- 测试人员在不断的更新测试包和等待出包上面浪费了大量的时间。
- 自动测试和专项测试只能在灰度阶段版本质量基本稳定的时候才能介入,这不但压缩了这些测试的时间,而且由于是在项目后期发现的问题所以会使问题修复成本增加。
- 非功能测试只有专项测试人员来做,此类测试的覆盖率还不理想。
- 测试经验的积累手段主要是自动化测试平台,但是这对于手淘研发团队来说还是远远不够的。
- 外包团队的组建解决了人力紧张的问题,但是外包人员的工作效果难以评估。
- 对于不同的环境需要打出多种不同配置的测试包(如:测试包、预发包、线上包等),测试人员需要安装多个包进行反复的回归测试。
当前阶段:多工程多构建产物、流程逐渐完善、多种质量保障手段建立
基于前两个阶段的经验和教训,手机淘宝研发团队在工程架构、研发流程、质量保障等多方面不断的进行完善,从而建立起来现在的体系。
工程架构
现在手机淘宝的工程架构进行了进一步的改造,形成了一套插件化的体系,而分 bundle 编译的引入大大缩短了构建时间,从而使构建速度不再成为瓶颈。另外分 bundle 编译可以提早发现编译问题,从而不会导致整包编译时编译失败。另外引入了依赖配置项的概念,目前项目完整包的构建完全取决于依赖配置,在单 bundle 开发、提测、项目集成、发布等各个阶段的依赖配置完全独立,各个 bundle 的开发测试人员可以在完全独立的环境中进行开发测试,不会受到干扰。
研发流程
有了工程架构的有力支持,研发流程慢慢进入了正轨。首先明确了 bundle 开发、提测、集成、灰度、正式发布等各个生命周期的边界,真正做到各个阶段的相互独立。其次在各个生命周期中加入了规范性的流程,并由平台保证了流程的真正实施。最后质量保证手段和效率也有了很大提升。基于以上几点手淘的整个研发做到了类似于火车发车的发布过程:
- 各个 bundle 在有着自己的需求、开发、测试计划,相互独立。
- 手机淘宝主项目制定发布计划,确定集成窗口和发布时间点。
- 在集成窗口时间 bundle 可以自主提交集成。
- 集成提交需要走流程,包括填写 checklist、代码检查、bug 统计、提前编译预集成包进行测试等。这就避免了明显的集成问题遗漏到集成环境中。
- 集成期间的集成包每天出一个或者两个,避免了测试人员不断拿包回归的情况。
- 集成窗口对于时间要求严格,赶不上计划或者质量不达标的 bundle 不予集成。这就是火车不等人的原则。
- 以上机制保证了手机淘宝每天都有一个候选包,可以随时进行灰度发布,并且灰度发布单独拉取一个依赖配置分支,不影响集成窗口。
- bundle 的独立,依赖配置的独立保证了手机淘宝可以并行多个发布计划,各个 bundle 可以按照需求自主决定搭乘哪个发布计划进行发布。
- 目前手淘项目节奏为两个星期发布一个版本。如果需要还可以更快的进行发版。最短只需要 1 个小时就可以发一个新版。
目前的平台建设工作也进入了快车道,所有的项目生命周期都有相应的平台工具支持,如下图:
质量保证手段
有了高效稳定的流程,剩下的事情就是如何保证产品在快节奏的持续交付下的保持很高的质量。质量保障上面手机淘宝研发团队做了几方面事情:
1. 流程方面
1)创建了提测单、集成单、发布单等流程。建立了标准,并依托平台自动检查,提高了交付的质量。
2)建立持续集成体系,不但能提早发现更多的问题,而且提升了测试人员拿到的包的质量。
3)建立线上线下监控分析体系。
2. 包稳定性方面:
1)bundle 阶段根据项目进度自己控制提测包的频率,集成阶段每日验证 DailyBuild 即可,所以解决了之前测试同学不断安装新版本的包的问题。
2)研发阶段的包内部支持环境切换,这实现了只构建一次,环境根据配置切换的梦想。测试时手机上只需要安装一次包即可完成多种环境下的测试。
3. 自动化测试与测试工具方面
1)引入多种静态扫描引擎,并定制多种规则:适配规则、Crash 规则、框架约定规则、安全规则等,并且不断地将测试阶段、线上问题等总结抽象成新的扫描规则补充进入扫描引擎。
2)在测试阶段包种插入相应的测试 SDK,并且这种 SDK 不会侵入应用代码,所以只需要在发布的时候去掉测试 SDK 即可。测试 SDK 可以在测试人员(包括外包适配测试人员)正常使用过程中自动检测并上报问题,这样就可以在同一的平台上看到研发过程中的质量情况并进行修复。
3)自动化平台方面也在根据手淘测试经验不断的进化,在整个研发过程中自动化测试一直在执行,不仅可以提高产品稳定性,也可以发现性能、电量等非功能问题。
4)mock 工具、验证平台等辅助测试工具也提升了测试人员的效率。
4. 线上线下监控分析
1)线下质量数据、线上业务问题、舆情反馈等信息统一汇集到平台上进行统一的分析告警,不仅能快速的发现问题,而且能通过数据分析能够帮助快速定位和解决问题。
2)根据平台中的数据,可以用经验推动流程的优化、补充测试用例、添加扫描规则、增加自动化场景、催生新的测试工具等,这样可以使经验形成闭环,使质量保障工作更加高效。
以上就是手机淘宝研发团队在建立高质量持续交付体系过程中的经验分享,虽然现在在架构、流程,质量保障方面有了一些积累,但是在移动互联网这个领域还有诸如稳定性、电量、流量、性能、适配、用户体验、线上运维、故障告警等难题等待我们去解决。前方的道路依然坎坷,我们会更加努力,并不断前行。
作者简介
杨强(花名:元战)阿里巴巴技术专家,2012 年加入阿里巴巴无线事业部,目前负责手机淘宝专项测试组,主要负责无线研发支撑平台,无线技术运维平台,无线专项测试工具以及无线 SDK 测试等方面的工作。曾经在趋势科技、华为从事测试工作。
感谢郭蕾对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。
评论