一直以来,在整个 IT 行业中,一说起测试这个工作,人们脑子中浮现的都是一群测试工程师用双手在键盘上或在手机上“点点点”的场景,所以很长一段时间,测试工程师都被戏称为“点点点”工程师。
不过,现在已经1202年了,如果还抱着这种态度来看待“测试”这个职业,未免有点太过时了。这就跟前几年台湾人民觉得祖国大陆人民吃不起茶叶蛋一样,“out的妈妈给out开门,out到家了”。
况且,现在的软件测试跟传统的软件测试相比已经发生了非常大的变化,不管是测试范围还是测试手段,都有很大的不同。所以,现在我们更专业的叫法是“测试开发工程师”,从这个名字就可以看出来,传统的点点点已经没有市场了,掌握开发技能的测试工程师才有未来。
不过光是这样说,其实对于很多未入行的童鞋,甚至是行业内做过多年但没有接触过测试职位的人来说,仍然不知道具体测试这玩意难在哪里(没办法,人一旦有了偏见就很难客观起来)。仅仅是多了个写代码的技能吗?那为什么不直接招几个开发来做测试,他们代码写得还更溜一些,还要啥测试开发工程师呢。
其实,真正所谓的“测试开发”,并不是简单地指“测试+开发=测试开发”,这其中蕴含着技术、流程、架构等一系列复杂的变化,现在要想做好一个大型复杂系统的测试是非常不容易的一件事。所以,今天这篇文章,咱们就聊细一点,让大家明白,我们说的测试很难,究竟是难在哪里。
为方便大家阅读,我把内容分为以下几个部分:
在最早的软件研发过程中,测试工作还只是整个研发过程中的一个阶段而已,如下图所示:
这个图很像一个瀑布的形状,所以我们把这种研发流程俗称为瀑布模型。大家从上面这幅图就可以看出,测试只在整个研发过程的差不多结尾的地方才开始。所以那时的系统大多都比较简单,功能也不复杂,但等产品都差不多开发完后再来测试,势必会带来很多风险。大家可以想象一下,这就如同修建一栋大楼,在差不多封顶时,才发现这栋大楼在打地基的时候就出了问题,后果不言而喻。所以,这样干是不行的。
既然不能这样干了,过了若干年,聪明的码农们又进一步改进了上面那个流程,这次改成了这样的一个 V 字型的流程,俗称 V 字型模型:
这个 V 字型模型的变化跟上面瀑布模型的变化其实不太大,但好在它相对清晰地划分了测试活动的不同级别,还将其不同级别的测试活动与软件开发各阶段清晰地对应了起来,旨在强调测试在整个开发过程中的重要性。但不幸的是,在 V 模型中,测试仍然是编码之后才开始的,测试介入的时间仍然太晚,比如需求阶段出的问题,要在系统测试阶段才能发现。所以还是不行,还得继续改。
随着时间的推进,另一个俗称 W 模型的过程出现了,大家应该可以猜到它就是长得像一个字母 W,如下图所示:
从上面的 W 模型示意图可以看出来,W 模型是把 V 模型左边的每一个活动都加了一个测试设计活动,这样就体现了“尽早和不断地进行测试”的原则,真正做到了测试前置。
不过,W 模型只是看起来很美,但它其实并不完美。因为不管是 W 模型也好,V 模型也罢,它们都把整个研发过程视为需求、设计、编码、测试等一系列串行的活动,无法支持快速迭代的研发需求及变更调整。而恰好这也是我们现在互联网产品的常态,996 短平快,是国内互联网产品的主流旋律,市场竞争如此激烈,没有哪个用户会等着你慢慢研发出来。
举个例子,遇到需要根据市场及监管要求,快速调整项目需求时,比如今年这个疫情,ZF 紧急要求上线全国人民都要使用的健康码监管系统,这种系统按照常规完整开发没个半年是搞不定的,但我们在短短一周内就上线使用,速度之快难以想象。这种时候如果按照 W 模型或 V 模型的串行做法,不仅无法快速响应,还会影响整个软件的质量,肯定是无法满足要求的。
终于到我们的迭代模型登场了,这才是现在主流的研发模型。所谓迭代,就是指将整个系统需求拆分成多个不同的小部分,一次只完成其中的一部分。这种开发方式的特点是小步快跑,增量实现,风险可控。所以,这种模式还有一个名称叫敏捷开发模式(Agile development)(我觉得发明这些词的人真他娘的是个天才,太形象了)。
在这种研发模式下,我们会将大型项目拆分为多个迭代,每个迭代本质上是一个小项目,每个项目都包含了需求分析、设计、编码、测试等一系列项目活动。由于它是增量的,所以它要求我们先完成部分系统功能或业务逻辑,然后依据客户反馈来进一步明确需求,最后通过一次次的迭代来给用户交付达标的产品。
比如,我们在实现一个大产品时,会先实现一个最小可用版本(MVP,Minimum Viable Product),然后等用户在使用过程中收集反馈,在后面的迭代中就能及时调整。
从以上这些研发模型的演进过程,我们可以看到,整个研发过程是随着技术与业务的变化逐渐演化的。而测试则在整个过程中,由最开始的最后一道工序,不断地前置,最终逐渐被提前到敏捷开发中的每一个迭代版本中,足以证明测试在软件研发过程中发挥着越来越重要的作用。
上一节我们聊完了不同研发模型的变化,接下来我们聊聊具体的技术层面的变化。其实在技术层面,不同开发模型所采用的开发、测试方式也不尽相同,这正是驱动 IT 行业技术发展的真正的原因。
简单地说,在传统的瀑布模型时代,大家都挺慢,系统需求也不会有太多变化,单纯美好的年代里,我们有足够的时间来准备详尽的测试计划、测试用例,慢慢地测。但如果在敏捷迭代的短频快开发模式下,事情就变得不那么美好了。
由于敏捷开发模式下,每个迭代周期最终都要开发一个完整的可用版本,所以在每一个迭代周期内,测试工程师都要进行完备的测试,以确保发布出去的软件产品是没有问题的。但每个迭代版本的周期又比过去的瀑布模式开发缩短了很多,这意味着相同时间内,你发布的次数增多了。而每一次发布版本都意味着你要快速回归所有重要的测试场景,这通常来说工作量非常巨大。
所以,测试不能等着编码完成之后再去完成了,那怎么办呢?这时,我们提出了测试左移和测试右移的概念。所谓测试左移,即测试往需求方向移动,介入到需求、设计、编码、集成过程中去,提前寻找可能存在的问题。而测试右移,则是指测试加入到发布后的流程中去,通过生产环境监控得来的各种数据去分析潜在的缺陷。
所以,现在质量已经不再单单是测试工程师的责任了,而是团队所有角色(开发、质量保证人员、技术运维)都要对产品质量负责。
最近几年业界流行的所谓 Devops(开发运维)其实就是开发、质量保证人员、运维三个角色的交集。Devops 旨在通过自动化的“软件交付”和“架构变更”的流程,来解决不同角色之间合作的流畅度,以及把软件交付的构建、测试、发布变得更加快捷、频繁和可靠,充分适应现代互联网产品短频快的特点。
Devops 在提高了公司的研发效率的情况下,也给测试人员带来又一个挑战:即如何在持续集成、持续部署的模式下保障质量?对于测试来说,如何把测试活动,特别是自动进行的测试活动无缝融合到公司的持续集成、持续部署框架下,将是一个非常大的挑战,也是未来大家在测试职业生涯上再走远一些,将要面对的问题。
微服务这词现在在 IT 行业非常火,几乎是大厂产品的标配了。怎么理解微服务呢?它也是一种产品实现模式,虽然微服务实现起来比较复杂,但理解起来相对来说还是比较容易的。你可以理解为,传统的开发是基于单体应用,就是不管功能再多,都是作为一个应用整体来进行构建和部署的。虽然有分层,但仍然是一个整体。而微服务模式下会将应用进行拆分,拆分成更小的独立服务,并使它们可以单独构建和部署。
微服务的引进提升了开发效率,降低了发布时间,但也带来了新的挑战:由于各个微服务常由不同的团队负责,并且各个服务之间普遍依赖 API 完成通信和调用,那么这些 API 之间的“契约”就变得非常重要,“契约测试”也就相应产生了。
还有,相较于传统单体应用,微服务的测试也更加复杂。仅从代码打包部署这件事儿来说,在单体应用里,不太会出现使用错测试包的情况,但是在微服务里,这个情况可能会发生。
单体应用,一个版本就对应一个代码分支;而使用微服务,每个微服务通常对应不同的代码分支。这就意味着在测试微服务时,测试不仅要关注你测试的微服务是否版本部署正确,还要检查其依赖的其他微服务的部署分支,查看其他微服务的分支是不是也部署正确。
除此之外,微服务的采用,也让我们的技术栈更为繁多、复杂,比如:
因为我解决微服务间复杂的通信和消息传递问题,引入了 RabbitMQ、RocketMQ、Kafka 各种消息中间件;
因为多个微服务的独立部署导致的环境依赖问题,引入了容器化技术 Docker; 容器越来越多,要解决其管理和维护问题而引入了
Kubernetes; 为简化故障定位问题,引入 ELK(Elasticsearch + Logstash + Kibana);
上线后,要对系统运行情况进行监控,因而引入了 Prometheus 与 Grafana 等;
以上“新”技术的引入,是为了不断应对软件开发演变中带来的各项需求和问题,解决了旧问题的同时,也为测试带来了新挑战,例如:
微服务独立部署、独立发布,那么微服务下的测试还能保持一成不变吗?以数据库举例,分库分表怎么来的?要怎么测试?
由于某些特殊情况(比如电商中的商品秒杀)而导致服务雪崩,微服务会引发熔断、降级、限流等一系列保护措施,要怎么保证这些措施被正确实施了?
持续集成,持续部署流水线建立了,以往的测试框架如何最小成本嵌入变成流水线的一环?
面对这些挑战,软件测试在快速演进的同时,也在裹挟前行,寻找破局之道。那么这个破局之道是什么呢?答案就是测试开发工程师。
正如前文所述,软件的发布动作变得越来越频繁,以往靠大量手工功能测试 + 少量主流程自动化测试 + 部分回归测试来保障质量的做法,变得越来越不现实。自动化测试,特别是不同层次的自动化测试在整个测试活动中的占比,正逐渐成为影响软件发布质量的关键。这也就是测试开发在近年来越来越受追捧的原因。
这么多的自动化测试用例,需不需要维护?如何维护?如何将自动化测试融入公司的持续集成流程中并自动触发运行?这些都是测试开发首要关注的问题,可以预料的是,随着交付频率的加快,测试开发会变成软件测试人员的基本技能。
所以,为什么我们一开始就说现在传统的点点点工程师已经没有出路,测试开发工程师才有未来,就是这个原因。
好了,现在大家应该都知道测试的挑战在哪里了。接下来,很多人关心的是,作为一个测试开发工程师,在职业生涯的不同阶段应该具备哪些技能,应该往什么方向发展才能让自己越来越值钱呢?接下来,我们分别来看看。
初级测试开发工程师的定位是:用开发手段让功能测试提高效率。
比如,帮助功能测试人员编写测试工具及测试框架,进而来提升功能测试的效率,也就是通过开发手段让功能测试变得更简单、快捷,该阶段的测试开发仅仅聚焦在开发这个纯粹的事情上。
举个例子,你通过编写自动化工具/框架,把本应该是手工执行的工作转换为机器自动运行;通过测试数据生成工具(Data Tools),让构造测试数据变得比以往更为简单。
所以,判断一个测试开发是否合格的标准,是看他能否让功能测试更省力。
高级测试开发不再局限于开发本身,而是从流程出发,检测公司整个软件开发周期中,哪个部分耗时最长,哪个部分最复杂,哪个部分最容易出错;然后资深测试开发就要改造现有流程,通过详尽分析、仔细论证,把最复杂、最容易出错的部分流程自动化掉,纳入当前的持续集成流水线中去。
这一阶段的测试开发,已经不满足于完成功能测试提出的开发需求,而是通过自己的开发技能,把测试各个阶段的任务有机地结合起来,经过消化后重新组织输出。
比如,以前公司没有持续集成、持续部署平台,代码打包都是开发或者测试人工去操作的,那么高级测试开发就要和整个开发团队合作,建立并完善这些流程。再比如,以前测试流水线没有建立,自动化测试脚本需要人工触发执行,那么,高级测试开发就需要把这些流程整合。
因此,判断一个高级测试开发是否合格的标准,是要看他的技术产出是否能融入公司的技术体系中去。换言之,就是要看功能测试的工作是否严重依赖他的产出:如果测试开发停工,那么功能测试就会很痛苦,甚至也被迫停工。
需要注意的是,这一阶段高级测试开发的产出,肯定非常贴切公司的情况,但未必符合其他公司的情况,或者未必跟业界的主流情况一致。
到了这个阶段,测试开发的重点已经不在测试本身了,而在于整个软件开发全流程的梳理。从项目立项开始,测试架构师就要规划当前的测试框架需要何种裁剪才能保证本项目顺利发布,并且在项目最开始阶段,通过测试左移的手段,对需求、开发技术方案进行分析,在保证可测试性的前提下,把公司现有的测试手段完美嵌入整个开发生命周期中。
在项目发布后,通过测试右移的手段,对生产系统进行监控,对系统本身或业务本身的各种线上情况进行分析,找出薄弱点,反查整个开发测试流程中的短板,然后补齐,从而保证产品的高质量和业务的高可用性。
判断一个测试架构师或者测试专家是否合格的标准,是看他能否在某个领域全部或者部分重新定义测试活动、测试顺序。换言之,这一阶段的工作产出,不仅仅适用于本公司,放到其他公司也可以,从方法论上来说,应该是普适的。
最后,我们总结一下,对于这三种不同阶段的测试开发工程师而言,
初级测试开发,即提升测试活动的效率,通过技术手段帮助功能测试工程师提升测试效率;
高级测试开发,即重构测试活动,技术产出完全融入公司的技术体系; 测试专家/测试架构师,即重新定义测试活动,输出普适的测试方法论。
好了,今天我们就先聊到这里,希望通过这篇文章,能够让更多“现在不是测试,未来想做测试”的童鞋对测试工作有更理性的认识,让大家看到测试行业的技术现状和发展,我们要做的一点也不比开发人员少。
了解测试行业的人,一定经常听到这样一种说法:测试究竟有没有存在的必要?面对这样的问题,作为测试工程师的我们来说,难免感到尴尬。但反过来我们也应该想想,为什么没有人说“开发究竟有没有存在的必要”这样的问题?我们如何才能为企业提供更大的价值?说句实话,相对于开发技术近几年能出不穷的各种发展,测试技术本身的发展是滞后的,我们不能再局限在传统的测试思维里发展,那样注定是无法提高的。不过好的一方面是,既然测试行业还有很多不足,意味着我们提升发展的空间还非常大,这从我们职业发展的角度来看,还是很不错的一件事。
总之,不管什么技术岗位,只有技术在不断向前发展,才不会被淘汰的一天,于我们每个人也是如此,希望与大家共勉。