微服务测试的思考与实践

最近几年,微服务架构越来越火爆,逐渐被企业所采用。随着软件架构的变化,对应的软件测试策略需要作何调整呢?本文将介绍微服务架构下的测试策略,并结合分享在业务和架构演变过程中,一个历经九年的项目测试策略的演进。

关于微服务

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,每个服务运行在其独立的进程中,服务间采用轻量级通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体的业务进行构建,并且能够被独立部署到生产环境、预生产环境。

从微服务的概念可以看出它有如下好处:

  • 每个服务可以独立开发
  • 处理的单元粒度更细
  • 单个服务支持独立部署和发布
  • 更有利于业务的扩展

同时,独立开发导致技术上的分离,HTTP通信加上Queue的机制增加了问题诊断的复杂度,对系统的功能、性能和安全方面的质量保障带来了很大的挑战。另外,服务间的复杂依赖关系带来了很多的不确定性,要实现独立部署,对运维也提出了更高的要求。微服务架构的系统要特别关注这几个方面:

  • 服务间的依赖、连通性
  • 服务的容错、可用性
  • 数据的最终一致性
  • 独立部署
  • 不确定性

测试策略的选择

谈到微服务的测试策略,很容易就想到了老马网站上Toby Clemson的文章《Microservices Testing》,该文推荐的微服务框架下的测试策略是这样的:

经典测试策略

这个策略模型强调测试分层以及每一层的恰当覆盖,整体符合金字塔结构。它是最优的吗?

有人对此提出了质疑…认为策略模型应该是蜂巢形状的(请参考文章):


这个模型重点关注服务间的集成测试,两端的单元测试和UI层E2E测试较少。

也有同事提出微服务下的测试结构应该是钻石形状的,服务间的集成依然是重点,单元测试较少,而顶层增加了安全和性能等非功能测试。

好像都有道理,到底选择什么样的策略模型好呢?不禁陷入了困境……怎么办?不妨先来听听我们项目的故事吧!

项目的故事

测试策略的演进

还是那个蓝鲸项目,不知不觉进入了第九个年头。在这九年里,随着业务的不断发展,系统架构也进行了多次演进和调整。相应的,测试策略也发生了有意思的演进变化。

测试策略的演进

最初单一用户系统、单体架构的时候,严格按照测试金字塔来组织各层的自动化测试。随着功能的扩展,大量mock的单元测试给重构带来了很大的不便。

企业系统开始开发的时候,我们调整了策略,减少单元测试的编写,增加UI层E2E测试的覆盖,测试结构由原来的金字塔演变成上面梯形下面倒三角的形式。

后来,架构调整,开始服务化。此时,大量的E2E测试渐渐暴露出问题:

  • CI上的测试执行时间越来越长,而且定位问题的能力很弱,测试一旦失败需要很长时间修复,测试人员好几天也拿不到可以测试的版本,反馈周期过长;
  • 由于服务化带来的不稳定因素增加,E2E测试没法很好的覆盖到需要的场景,测试人员就算拿到可测的版本也总有各种缺陷发生。

因此,项目引入契约测试,停止编写新的E2E测试,将测试下移,分别用API测试和契约测试取代。

随着功能的不断增加,虽然E2E测试的量并不增加,但是其不稳定性、维护难、定位难的问题有增无减,此时已经很难由自动化测试来保证产品的质量。为了平衡成本和收益,项目考虑去掉大部分E2E测试,只保留少量的Smoke测试,将更多的测试下移。

同时,技术雷达上新的技术“生产环境下的QA”出现,项目也开始关心生产环境,并且在QA测试阶段结合微服务的特点进行对应的探索式测试。

应对微服务的挑战

前文提到过微服务带来的挑战,下面来看项目是如何应对这些挑战的。

  • 服务间的依赖、连通性

微服务架构下,独立开发的服务要整合起来最具挑战,如何保证服务间的依赖关系和连通性非常关键。前面已经讲过E2E集成测试有很大的挑战,并不适合,而消费端驱动的契约测试是个不错的选择。项目正是利用契约测试去保证服务间的连通性,取代一部分E2E集成测试。

  • 服务的容错、可用性

在系统负荷达到一定程度或者某个服务出现故障的时候,微服务架构有两种技术来确保系统的可用性:服务的熔断和降级。服务的熔断是指当某个服务出现故障时,为了保证系统整体的可用性,会关闭掉出现故障的服务;服务的降级则是当系统整体负荷过载的时候,考虑关闭某些外围服务来保证系统的整体可用性。

对应的测试包括:

  1. 熔断:从性能角度,当系统负载达到某个熔断状态的时候,服务是否能正确熔断;同时,从功能角度验证熔断后系统的行为是否跟预期相符;
  2. 降级:从业务的角度,要能区分出核心业务和外围业务,在需要降级的时候不能影响核心业务;当某个服务降级后,从功能角度验证系统行为是否跟预期相符。
  • 数据的最终一致性

数据一致性是微服务特别需要关注的。举个例子,电商平台某个订单支付成功以后,需要更新积分和订单状态,当订单服务或者积分服务其中有一个出现故障的时候,就会导致最终的数据不一致性。

测试这种情况,从业务的角度分析哪些服务会导致数据不一致性,制造对应的异常情况去测试数据的最终一致性。

  • 独立部署

微服务的独立部署需要有CI、CD的支持,跟DevOps实践分不开。同时,更为关键的是需要契约测试来验证独立部署后服务行为的正确性。项目在这方面的工作,请参考王健的文章:你的微服务敢独立交付吗?

  • 不确定性

微服务架构使得系统复杂度增加不少,很多的事情发生都是不可预测的,只能在其发生以后找到产生的原因。因此,也就没法在预生产环境通过测试去发现在真实生产环境才会发生的issue,我们需要把目光转移到生产环境,利用生产环境的不确定性、微服务的不可预测性来构建反脆弱的系统。

项目在这方面主要采用的技术是生产环境下的QA,请参考文章:生产环境下的QA

项目测试策略

从前面介绍的演进过程可以看到,项目测试策略在不同阶段结合参考了不同的策略模型:金字塔->近似钻石(除非功能测试外,类似于钻石模型)->蜂巢。后期全面服务化的时候,我们认为蜂巢模型是比较适合的。

当然,光有符合这个策略模型的自动化测试是远远不够的,我们项目还采用了针对微服务特点的探索式测试,保持持续交付节奏,践行DevOps实践,结合生产环境下的QA等技术把关注点右移到生产环境。

现在,项目整体测试策略演变成下图的形式:

  1. 项目采用的是敏捷迭代开发和持续交付的模式,每四周一个发布周期。
  2. 在开发过程中实现的自动化测试是分层实现的:底层少量的单元测试,中间量最多的是API测试(类似于老马推荐的策略模型里的组件测试),上面有一部分契约测试和少量的Smoke测试来保证服务间的契约和集成。除此之外,QA有手动的探索式测试,其中包括针对微服务特点进行的一些测试。整个测试结构是类似于蜂巢模型的。
  3. 采用生产环境下的QA技术,利用生产环境,进行error监控、用户行为分析、用户反馈收集,从而来影响和指导预生产环境的开发和测试工作。
  4. 利用DevOps实践,做到高效的部署和监控,跟生产环境下的QA结合,形成良性的环路,保证项目的正常交付。

测试策略再思考

项目上多次测试策略的调整,看似很简单,其实每次调整并不是一个轻松的过程,都是平衡利弊、综合考虑多个因素才做出的决定。

分析整个调整过程,最后突然发现:当我们面对多个策略模型不知道如何选择的时候,其实我们陷入了一个太过于关注测试结构的误区,忘记了最初的目标是什么。

影响测试策略的因素

跳出误区,回到原点,重新思考测试策略的目标。影响策略的最关键因素是业务价值、质量要求、痛点。

  • 业务价值

带来更大的业务价值、帮企业赢得更多的利润,是软件系统的目标;软件测试是软件系统成功的保障之一,业务价值也是测试策略的终极目标。所有测试活动都要围绕这个目标开展,考虑业务优先级,有效规避业务风险。

  • 质量要求

不同的系统、同一系统的不同利益干系人(参与的不同角色)对于质量的定义和要求都可能是不同的,这毫无疑问是影响测试策略的一个关键因素。

对于仅有内部用户的系统,关注的重心可能是系统的功能;而对外发布的产品,则要求更高,一个按钮位置的不恰当都可能带来大量用户的流失。

  • 痛点

真正的痛点往往也是优先级最高,迫切需要解决的。那些可以通过测试策略的调整来解决的痛点,自然成为了关键的影响因素之一。比如,CI Pipeline出包太慢,为了提高出包的效率,一方面在Pipeline本身想办法,另一方面调整自动化测试的比例、执行频率等也是解决方案之一。

演进式测试策略

处在不同阶段的项目,在业务价值这个大目标下,其他影响因素也是会不一样的,跟技术架构的演进一样,测试策略也应该是演进式的。

从目标出发,综合所处阶段各个方面的影响因素,制定出适合当时的测试策略。随着时间的推移,对策略进行评估和度量,并进一步改进、提高,以更好的满足需求。这就是目标驱动的演进式测试策略。

总结

微服务架构下多个服务的整合是最具有挑战的,对此最重要的是契约测试。契约测试有效保证服务间的契约关系不被破坏,确保服务的连通性,有助于实现真正的独立部署和独立交付。

微服务架构引入的不确定性并不是坏事,可以利用这些不确定性,采用生产环境下的QA等技术,增强系统的反脆弱性,从中获益。

测试策略的影响因素不是唯一的,技术架构并不是最关键的因素。微服务架构下的测试策略跟其他架构下的并不会有本质的区别。

业务价值始终是我们的终极目标。在这个终极目标的驱动下,测试策略不是制定完了就可以束之高阁的,需要在整个软件系统构建过程中不断的度量和改进,是演进式的。

聚焦测试,驱动卓越

在经历了“七年之痒”后,蓝鲸项目进入第八个年头,项目的一切趋于稳定。团队倡导持续改进,可大家的感觉是已经尽力做到最好,这个时候似乎没有什么可以改进的了。为了突破这个局面,项目重新聚焦测试,从质量和测试的角度对现状进行了一次评估。

评估采用的是基于软件测试原则的模型,本文就是跟大家分享一下这个模型。

测试原则

Testing principles

2012年澳大利亚敏捷大会(Agile Australia)上ThoughtWorks的非常资深的测试实践带头人Kristan Vingrys分享了如上测试原则,这些原则是ThoughtWorks的同事们在多年软件测试经验基础上总结出来的。

1. 质量内建(Build quality in)

You cannot inspect quality into the product; it is already there.
— W.Edwards Deming

著名的质量管理专家戴明指出:产品质量不是检测出来的,从产品生产出来后质量就已经在那了。这同样适用于软件产品。

缺陷发现的越晚,修复的成本就越高。质量内建要求我们做好软件开发每个环节,尽早预防缺陷产生,以降低缺陷出现后的修复成本,要减少对创可贴式的补丁(hotfix)的依赖。

Cost of change

推荐实践: TDD、ATDD等

2. 快速反馈(Fast feedback)

每个环节的任何变化都能最快的反馈给需要的人,从而可以基于当下最新信息做出明智的决定,降低风险。这要求我们对系统进行频繁的测试,缩短回归测试的周期。

推荐实践:

  • 符合测试金字塔结构的自动化测试,让每一层的测试都能发挥尽可能大的价值,给出最快速的反馈;
  • 持续集成,尽早排查集成引起的问题,降低集成所带来的风险。
3. 全员参与(Involve everyone)

— 这次上线好多bug,QA是怎么测的?!
— 那个xxx组在上线前发现了很多的bug,他们的QA真给力!

成也QA,败也QA…如果还是这样的认识,那是极为片面的。测试不仅仅是QA的事情,团队成员要一起为质量负责,软件开发生命周期的测试相关活动需要全员的参与。

全员参与的好处是利用不同角色的不同领域知识和不同的思维模式,不仅可以使得测试的质量更高,同时还能最优化利用测试资源,做到价值最大化。

推荐实践:

  • 自动化测试:QA和BA结对用DSL编写测试用例,QA和Dev结对编码实现测试,生成业务人员可读的测试报告;
  • Bug bash(bug大扫除):团队不同角色一起参与的一个找bug的测试活动
4. 测试作为资产(Tests as asset)

自动化测试帮助我们验证系统功能的正确性,好的自动化测试还有文档的功能,是宝贵的资产。如果每个项目都构建自己独立的自动化测试,没有跨项目共享,其浪费显而易见。

这个原则要求把自动化测试的代码跟产品开发的代码一起,当做资产管理起来,在不同项目间做到尽可能的复用。这笔宝贵的资产能帮助我们更好的统计跨项目的测试覆盖率,更好的优化测试。

推荐实践:利用版本控制管理工具把测试代码和产品构建代码一起管理,都作为产品的一部分。

5. 更快的交付(Faster delivery into production)

任何一个idea越快做成软件产品交付给用户,给企业带来的价值越大。

该原则要求我们把测试活动融入软件开发生命周期的每个环节,不要在后期进行长时间的集中测试;同时测试人员的关注点不再是发现更多的bug以阻止不符合质量要求的产品上线,而是把目标放在如何能够帮助团队尽快的让产品上线,让企业投资回报更早,也就是更快的赚钱。

推荐实践:自动化构建流水线、关注平均恢复时间、发布与部署解耦等。

Pipeline
6. 清晰一致的测试视图(Clear and consistent view of testing)

可视化的报告给客户和内部团队展示测试的状态和产品内外部的质量,对项目的质量和风险把控是非常有帮助的。不同项目各自采用五花八门的图表样式,将不利于项目间的信息共享和比较,无端增加复杂性,带来浪费。

因此,我们需要把状态报告做的尽可能简单、清晰,并且保持跨项目的指标一致性;同时,我们不应该为了让某个指标变得好看而改变我们的行为,整个报告要诚实开放,这样才能真实反映出项目的状况。

7. 优化业务价值(Optimize business value)

开发软件无疑是要给客户的业务带来价值,软件测试也需要为这个目标服务,测试要跟业务价值保持一致,帮助客户优化业务价值。要求做到:

  • 测试不仅是保险,不仅是保证软件质量的;
  • 要有目的的关注变化的特性,不要盲目的散弹枪式的对任何特性进行测试,要有优先级;
  • 要能帮助企业驱动新的特性和功能;
  • 帮助客户创造安全的尝试新点子的环境,提供快速的反馈。

推荐实践:

  • 基于风险的测试,根据业务优先级需要调整测试策略,在测试过程中尽可能规避给业务带来的风险;
  • 生产环境下的QA,通过收集生产环境的真实用户行为和应用使用数据,对业务的优化做出贡献。

评估模型以及在项目中的应用

评估模型就是将上述七条原则的每一条细化,列出该原则对应的实践和行为,并给每个实践或行为设定0-5分的不同评分标准,最后统计各个原则的总分,形成类似下图的结果报告:

Result Model

在项目中的应用

以Cristan分享的模型为基础,由Tech Lead和几个DEV、QA成立一个评估小组。

第一步:分别根据各自的理解给项目打分,结果是很有意思的,请看下图:

结果对比图

根据这些结果,可以看出大家的认识是不太一致的。

第二步:评估小组对模型中的每条细节进行review,做适当修改以更符合项目情况,并且在评估小组内大家达成共识。其中,所做的修改包括修改原有的实践评分指标、增加新的更适合项目和当前技术趋势的实践、删除过时的或者不符合项目特点的实践。

第三步:根据更新过后的模型指标对项目上的一个Team做评估试点,详细分析该team对应到测试原则各个维度的well和less well部分,由评估小组成员一起打分,得到该team的评估结果图。

第四步:根据评估结果并结合项目目标排定需要改进的优先级,制定出改进action,并更新给试点team执行。

后续:试点一个周期后再次评估,并重新review评估模型,再推行到整个项目。同时,周期性的进行新的评估和制定新的action,以做到持续的改进和优化。

总结

图片来自网络

应用程序的质量、测试的快速性、以及上线后轻松自信的更新服务的能力,是帮助企业业务价值最大化的关键因素之一,一直是我们所追求的。

基于测试原则的评估模型,可以帮助我们在追求这个目标的道路上少走弯路,帮助我们持续的改进,以驱动出更加卓越的软件。

物联网测试地图(译)

物联网的出现,给测试带来了很多有意思的挑战,使得众多QA开始重新思考传统的测试过程。

例如,我最近测试了一个产品,在这个产品中的移动APP会跟连接的机器产生会话。这两个设备各种各样的状态给测试场景的设计带来了特别大的挑战。下面给大家介绍一个很有用的物联网产品测试框架——物联网测试地图,它可以帮助我们管理物联网设备多种排列的复杂状态。

物联网测试因素

当我们测试简单的web应用时,通常要考虑的状态有:

  • 服务器宕机
  • HTTP请求超时
  • 网速慢
  • 授权和认证错误

测试任何互联网应用的时候,需要警惕这四种状态。对于移动应用,操作的是移动环境,需要关注额外的几种情况:

  • 离线模式
  • 在线模式
  • 杀掉Activity
  • 后台行为
  • 语言
  • 地理位置

我们再看“连接的机器”所带来的状态多样性,通常还有:

  • 机器WiFi断开
  • 机器WiFi连接
  • 机器繁忙
  • 机器休眠

这意味着即使只有上述给定的状态集,整个系统在任何时间点上可能会有96(4x6x4)种状态。

由于系统中状态转换会引入附加的约束,这些状态都不能当做独立的实体。例如,状态从“离线”变成“在线”很可能触发一系列的事件。

上述因素还仅仅是冰山一角。随着对规范的深入了解,把不同的状态跟逻辑场景结合起来将会更加的复杂。

对于静态系统的可变数据集,已有的web测试技术可以很好的用来抽取测试场景,比如all pairs(开源的配对测试工具)、等价类划分、边界值分析法等。这些技术通过淘汰的逻辑来优化测试数据集。

例如,all pairs技术会淘汰重复的数据配对组合。但是,对系统的可变状态设计测试场景时,这些技术是不可靠的,废弃的系统状态会使得系统通讯不畅。当然,这些技术对于物联网系统中的单个单元还是很适用的。

因此,非常有必要搞一个物联网测试地图。

可视化地图

大家肯定都在地理课上看过地图。但我这里所说的地图是针对测试场景的,它列出所有潜在的系统因素,在测试某个特性时可以从中抽取必要的测试场景。

产品的每个系统的n种状态在同一个可转动的圆环中列出,逻辑上相邻的状态在环中相互挨着。非功能需求(NFR)在测试复杂集成的时候很容易被忽略掉,于是把它们在一个环中单独列出。

下图就是我所说的物联网测试地图:

物联网测试地图

下面以一个例子介绍地图的使用场景,该例子仅涉及移动设备和机器交互部分,需要关注的环是设备、机器和网络。

把移动设备和机器固定在WiFi连接的状态,转动网络环,可以得到下面这些场景:
  • 未授权用户尝试访问机器会在App上触发“访问被拒绝”的错误消息
  • 服务器宕机和服务器错误会触发相应的业务错误消息——“程序出错,请稍后重试”
  • 响应超时可能有两种情形:重发同一个请求并显示“正在加载”图示,或者显示上面那样相似的错误消息
  • 非法请求会触发消息“请更新你的App”
继续保持移动设备的WiFi为连接状态,转动机器环:
  • 当机器是离线模式的时候,App应该显示“请检查机器的网络连接”
  • 当机器繁忙的时候,弹出警告“机器繁忙,无法完成请求”
  • 当机器休眠或者在另一个网络上的时候,应该显示“没找到机器”等类似的消息
  • 然后,机器调到正确的网络,应该恢复移动设备和机器的连接
切换机器环为WiFi连接,转动移动设备环:
  • 当移动设备离线时,应该弹出对应的消息或者禁掉操作按钮
  • 当移动设备恢复在线模式时,App应该发送相应的请求去连接机器
  • 当移动设备的网络从WiFi切换到3G,应该有什么样的行为?
  • 当用户正在试图连接物联网设备的时候突然接到电话,将App置于后台运行,这时候还能收到完整的请求还是需要从头开始发送请求?
  • 安卓设备杀掉一个在后台运行了一段时间的App,用户的最后屏幕状态还会保存吗?
  • 有本地化需求的App要在每个场景层面进行验证

就这样,多次旋转地图可以扩展产生多个场景。尽管有些场景可能不适合当前的特性,有些甚至跟业务需求无关,这个测试地图还是非常详尽的。

在实践层面,对于有多个QA在测试同一个物联网产品的团队,地图可以作为大家共同参考的手册。这个地图把工具、设备、场景和协议的排列以易于理解的方式呈现出来,覆盖了测试场景设计这个独特的需求,是一种非常高效的合作方式。


  1. 此文发表于:TW洞见
  2. 英文原文请参考:IoT Testing Atlas

系统级集成测试的断舍离

食之无味,弃之可惜

在企业级应用的季度或月度发布被认为是领域最佳实践的时候,应用部署到生产环境之前维护一个完整的环境进行集成测试是非常必要的。但是,集成测试环境和集成测试本身有着如下的问题:

  • 环境本身脆弱,而且通常存在手动配置部分,环境维护成本很高;
  • 环境因素导致集成测试不稳定、不可靠、反馈慢,测试失败不易定位问题,同时还会重复测试隔离组件已经测过的功能。

集成测试成为了持续交付的瓶颈,犹如鸡肋。因此,最新一期(2017年第16期)ThoughtWorks技术雷达建议企业暂缓搭建企业级集成测试环境,而是采用增量的方式发布关键组件到生产环境。增量发布涉及到一些重要的技术包括契约测试、将发布与部署解耦、专注于平均恢复时间和生产环境下的QA 。

技术雷达之集成测试

断舍离之技术可行性

下面分别介绍技术雷达建议的这四项技术,以及在没有集成测试的情况下如何保证应用的质量、如何帮助企业做到独立增量发布。

消费端驱动的契约测试

消费端驱动的契约测试是微服务测试的重要组成部分,主要用来覆盖两两服务之间的契约关系,下面举个例子来说明什么是契约测试以及契约测试与API测试的区别。

插头与插座

家里有个插座,买电器的时候需要考虑插头跟插座是能配对的,也就是说插座和插头之间需要有契约。

这里的契约测试就是插座跟插头的配套性测试,包括

  1. 三相/三头还是两相/两头的;
  2. 电压是220V还是 110V;
  3. 插孔的形状:英式?中式?
  4. 等等

API测试:对于插座本身功能的测试,需要覆盖

  1. 插座能够正常通电;
  2. 电压是预期的220v;
  3. 接地的插孔真的能够接地
  4. 等等

也就是说API测试需要测试API本身功能的各个方面,而契约测试重点在覆盖API调用的格式、参数数量、参数类型等,不一定需要涉及API本身的功能和具体的数据。

更多关于消费端驱动的契约测试,请参看文章《Consumer-Driven Contracts: A Service Evolution Patter》。

发布与部署解耦

部署,就是把组件或者基础设施部署到生产环境,不对用户可见,不会影响业务和用户的使用。发布,则是将部署的组件让用户可见,对业务会产生影响。可以通过采用Feature toggle的方式实现部署与发布的解耦,做到持续部署和可控制的发布,减少组件改变带来的风险。这样,产品经理可以根据业务需求灵活控制发布给最终用户的功能组件,帮助企业业务价值最大化。

关注平均恢复时间

先看这样两种情况,思考哪种更好:

  1. 系统宕机次数很少,可能每年也就一到两次次,但是恢复能力很弱,一旦宕机,得花至少24个小时恢复正常;
  2. 系统宕机频率较高,不过每次宕机都能快速恢复,用户甚至感觉不到。

对于第一种,平均失败间隔很长,但是一旦失败对用户的影响不言而喻;第二种虽然有频繁的失败,但是平均恢复时间很短,用户体验不受影响,当然是第二种更好。

传统的Ops团队比较关注失败发生的频率,随着持续交付和监控技术的发展,快速恢复成为可能。不用担心错误、失败的发生,而是利用对这些错误和失败的监控和分析,让系统做到快速恢复,可以省掉一些复杂的集成测试,也可以减少无处不在的安全攻击的影响。

生产环境下的QA

生产环境是真实用户使用的环境,通常都不能跟测试环境那样可以在上面直接测试产品的功能,不能简单的把测试环境所用的的QA技术直接后延到生产环境,而其中一项在生产环境使用的技术就是监控。采用监控技术来获取生产环境的信息,对其进行分析,然后优化开发、测试过程,同时优化企业业务。更多关于生产环境下QA的内容,请参看文章《生产环境下的QA

对上面四种技术的解释,我们可以看到:契约测试是对持续独立部署有帮助的,监控技术则是缩短平均恢复时间和做好生产环境下的QA共同的关键技术之一。接下来主要分享项目在围绕契约测试和日志监控这两块所做的实践,一起来看系统级集成测试的断舍离该如何实现。

断舍离之项目实践

项目是一个开发了七八年的老项目,团队对集成测试也是进行了多次的调整,经历了“七年之痒”后依然觉得是鸡肋:

  1. pipeline上执行非常不稳定,总是“随机挂”,不能真实反映问题;
  2. 系统复杂,集成测试自然也不简单,每次顺利执行的时间都需要半个小时以上,何况还有很不稳定的情况,最严重的时候导致QA超过一周拿不到包部署;
  3. 通过集成测试发现的应用程序的缺陷半年也难得出现一个;
  4. 随着系统逐渐变得复杂,集成测试维护的成本也不断增加。

可以看出,集成测试已经严重阻碍了项目持续交付的进行,不得不对其断舍离了。

(一)测试策略调整

断舍离的第一个部分是从集成测试本身入手,调整测试策略。步骤如下:

  1. 不再添加新的功能层面的自动化测试,原有的集成测试部分能用底层的UT、API测试覆盖的尽量下移;
  2. UT和API测试不能cover的服务间的契约关系通过增加契约测试来保证;
  3. 从CI上摘掉原来的集成测试,加速pipeline出包,然后添加Smoke测试到QA环境执行;
  4. 不管是在测试环境还是生产环境发现缺陷,则添加对应的测试。

整体策略调整思路是根据测试金字塔的结构进行调整,把测试尽量往下层移,但并没有全部去掉集成测试,只是缩减到非常关键的路径覆盖,最终测试结构调整如下图所示:

项目测试金字塔

(二)日志监控、分析和优化

没有了Pipeline上的集成测试,直接上到QA或者prod环境,那么加强日志监控变得尤其重要。因此,断舍离的第二个部分是日志的监控、分析和优化。

**日志数据采集 **
项目使用的日志分析工具是Splunk,使用该工具从下面几个方面来着手采集日志数据:

  1. 在Splunk上设置日志监控的Dashboard,主要用来监控API的请求失败、错误的日志,还有API执行时间等性能相关内容。如下图所示:
监控Dashboard
  1. 设置预警邮件提醒:对于一些存在严重性能问题的API请求,通过邮件的方式进行预警提醒,如下图:
预警邮件
  1. 主动查找错误日志:对于一些生产环境用户反馈回来的问题,通过主动查找错误日志的方式去定位。
  2. 前面的几个机制同样应用于QA和Staging等测试环境,以通过日志分析尽量提前发现问题。

日志数据利用

利用前面几种方式采集到的日志数据,从下面几个方面进行分析和优化:

  1. 发现和定位系统功能问题,分析系统用户的行为习惯,优化业务;
  2. 发现和定位安全、性能等非功能问题,进行修复和优化;
  3. 发现和分析日志记录本身的不足,规范日志记录,从而进一步增强日志给问题诊断带来的帮助,形成良性循环。规范日志记录主要涉及这些点:统一日志输出路径、统一日志记录格式、清晰定义日志级别,并且把添加必要日志作为story开发流程的一部分,QA会参与日志评审。下图是Splunk里看到的项目最新优化的日志记录格式:
日志

项目对集成测试断舍离才刚刚开始,正在不断摸索着前进,目前能看到的最直接的影响是pipeline出包明显加快,由以前的好几天出不来一个包变成一天能出好几个包。最让人振奋人心的是本周刚刚发生的事情:前一天下班前报的bug,第二天上午就已经修复出包可以测试了。

写在最后

系统级集成测试虽然有各种问题,不一定会因为集成测试挂掉而发现很多问题,前面也讨论了断舍离的可行性,分析了项目断舍离的实践,但集成测试并不是用来发现问题的,而是一道对质量把关的屏障,关键路径的必要测试是不可替代的。因此,我们提倡减少集成测试的数量,合理调整各层测试的比例。

系统级集成测试的断舍离需要团队有持续、递进、稳定的交付能力,需要保证用户不会受此影响,企业业务能够正常运转。系统级集成测试的断舍离过程不是一蹴而就的,凝结在集成测试上的心血也不是那么容易放弃的,需要很多的平衡和取舍,并在整个过程中要不断的关注系统的质量和风险,及时作出相应的调整。

为什么不能每周发布一次?

图片发自简书App

“看,车来了!不过这趟车貌似咱赶不上了吧?!”
“啊!那快点跑,错过这趟就得再等半个小时!”
……

好无奈,可是真的赶不上也没有办法,这个场景很多人都经历过。

“这个release又是一定包就开始上hotfix,四天跟了四个,我根本没时间做回归测试!” QA小静同学抱怨道。
“每次都是定包后就开始无休止的上hotfix,咱们还不如改成每周发布一次!”Dev大鹏同学也被hotfix折磨苦了。

这是发生在蓝鲸项目的一次真实而平常的对话,跟前面赶公交车的场景有什么关系呢?

发车间隔与发布周期

发车间隔的不同带给乘客的感受会完全不同。

有些公交车很少,每半个小时一趟,有时候眼看着一辆车来了又走了,没赶上的心情无比懊恼,下一趟还得等上半个小时啊!实在着急的可能考虑叫一辆快车赶紧走…

而有些公交车发车间隔非常短,几分钟一趟,就算错过一趟也无需等待太久,只要不是着急去救火的乘客一般都不会太在乎。

图片发自简书App

项目的不同发布周期带给客户的感受也是类似的。

蓝鲸项目的发布周期跟第一种公交车发车间隔非常类似,是四周发布一次,如果这次没能上线的功能,或者有导致功能不能正常工作的缺陷,下次发布上的话,就得再等一个月。一个月,那是多少白花花的银子啊!对于那些特别重要的功能,客户着急就要求上hotfix,于是就出现了前面小静和大鹏对话中的场景。

Hotfix是否真的能解决软件交付过程中的问题呢?其实不然。

Hotfix的引入带来很多额外的工作,影响新功能的按时交付,会打乱交付节奏,从而有形成恶性循环的趋势。既然这样,大家一定希望能解决,而且通过公交车的例子很容易想到前面大鹏说的那个方案。

如果发布周期缩短,比如说一周甚至更短,这次没上的功能也不用那么着急的通过hotfix来上线,就能解决问题。那么蓝鲸项目为什么不一周发布一次呢?

如何才能缩短发布周期?

发布周期的影响因素

1. 合适的迭代计划和合理的需求切分

半个小时一趟的公交车,就算车子足够大能够承载半个小时到达的乘客数,可是会导致乘客等待时间过长,造成很多不便和耽误。要解决这种情况,可以把大型公交车换成多辆小型车,增加发车次数,缩短发车间隔。发车间隔缩短到多少,车子换成多大的都是需要仔细分析和考虑的问题。

映射到蓝鲸项目,要缩短发布周期,就得有相应的小规模需求正好能够乘坐小发布周期那样的小车,要做好发布计划和需求切分。

这样,对需求源的要求很高,需要客户那头的紧密配合。要想缩短发布周期,首先必须得有足够的、粒度合适的功能需求,能够正好安排到较短的发布周期上线。如果需求范围不能提前确定好,就没法提前做好短周期发布计划,不可能把发布周期缩短。

2. 强大的开发能力

乘客的需求分析清楚了,要想缩短发车间隔非常关键的一点就是要有足够的安全的车和靠谱的司机。 如果这一点满足不了,其他都免谈。

对应到蓝鲸项目,安全的车子和靠谱的司机组成了团队强大的开发能力,包括架构支撑和人员技能。

车子就是对持续交付友好的技术架构,需要减少模块间的依赖,比如采用微服务。蓝鲸项目是一个七年之久的老项目,很多陈年依赖已经形成,要拆分不是一时半会的事情,团队正在朝着这个方向努力。

司机就是我们的开发团队,除了要有必要的开发技能外,要做到靠谱就得透彻理解持续交付的精髓,需要团队人人都有质量意识,人人都有发布周期的紧迫感,并且能够做到高效合作,从需求划分、代码质量、测试保障等做好各个环节的工作,做好缺陷的预防和监控,不让严重缺陷流入后面阶段。

蓝鲸项目由于新人较多、人员流动大等原因,对于质量意识和紧迫感都有待提高。 不过,在各位QA的影响下,团队人员的质量意识、紧迫感都在改善,新人的技能也在不断的学习和实践中得到提高,但仍然不能放松警惕,需要时刻保持向前的精神面貌。

3. 充分必要的测试支撑

有了足够的安全的车和靠谱的司机,还得保证路况足够好,这样才能做到不管到达哪个站,间隔都是相同的。

要想蓝鲸项目的持续交付能够顺利前行,一路畅通,需要严格做好质量内建,各层都有充分必要的自动化测试保护,减少新功能开发过程中对老功能的破坏;同时持续集成流水线也要很健全,不能耽误代码提交和出包,从而影响开发和测试的进度。

蓝鲸项目开发年限已久,复杂度很高,在持续交付的路上行走的有些坎坷。目前团队正在这些方面努力采取改进措施,取得了不少进展,但确实还有不少提高的空间。

前景堪忧?

图片发自简书App

过去七年,蓝鲸的持续交付之路有些坎坷,但不应因此而失去信心。

通过跟公交系统的对比,我们可以看到蓝鲸项目要缩短发布周期、杜绝hotfix,需要从需求切分、迭代规划、技术架构、团队能力和测试策略等多方面进行优化,才能保证持续、快速的发布节奏,这是一个系统的问题。

七年之痒已经平安度过,蓝鲸团队正在采取相应的改进措施,一旦做好了上述各方面的优化,相信下一个七年一周发布一次或者更短发布周期都将不是梦!

大规模团队的QA如何高效合作

“你们团队QA和DEV的人员比例是多少?”
“我们团队一般有1个QA和3~4对DEV pair.”

经常会被问到这样的问题,一般的小团队都是这样的人员比例,QA也不会觉得压力有多大。当多个特性团队工作在同一个代码库、分别在开发同一个系统的不同功能的时候,虽然每个特性团队也保持前面所述的比例,对于QA的挑战却要大得多,那是因为:

  • QA不仅要了解自己特性团队的需求,还需要了解其他团队的需求,因为这些功能都在同一个系统上,联系必然是很紧密的;
  • 某个团队发现的软件缺陷的根源、错误日志信息,在其他团队也可能发生,这些信息需要共享;
  • 某个特性团队有任何基础设施、测试环境配置文件的变化都得让所有团队知晓,而QA是其中沟通这个内容最恰当的角色;
  • ……
图片来自网络
(图片来自网络)

由此可见,大规模团队的QA不像小团队那么简单,沟通的成本要高很多。如果没有及时沟通,将会造成信息不对称,要补救所花费的额外精力是比较大的。当然,大规模团队不仅QA的沟通成本增加,其他角色也一样,只是因为我是QA嘛,就跟大家聊聊我们QA是如何应对这种大规模团队的挑战的。

集体参加story的kickoff和desk check

不管哪个组有kickoff和desk check,各组的QA都一起参加,这样基本能搞清楚各个团队都在开发什么功能。只有两三个特性团队的时候,这个方法还勉强行得通。但随着团队越来越多,在高峰期的时候,QA可能一天都在这两个活动中切换,通过这种方式了解各组的需求似乎不是一种高效的方式……

集体参加各组的feature kickoff

一个release做一个feature的话,QA参加feature kickoff每个release只需要参加一次,貌似还可以的样子。但由于各组的发布周期是一样的,各组做feature kickoff的时候,QA正是忙着上一个发布周期验收测试的收尾阶段,同时也是忙着review自己所在特性团队story的时候,一般都比较忙,尤其特性团队越来越多,如果还要集中参加其他组的feature kickoff,一定会忙不开……

前面这两项我们团队都有实践过,但显然都没能很好的坚持,因为手头的确有些忙不过来,这些自然优先级就变低了。大家始终坚信信息共享的重要性,于是团队在不断摸索中找到以下两种方式。

定期catch up

定一个每周一次的例会,要求QA们合理安排手头工作,务必参加该例会。例会上每个人
给大家介绍自己组内的feature,更新状态,把遇到的困难、blocker、风险等拿出来跟大家一起讨论,讨论对策,并且对一些接下来要做的事情清晰列出来,找到专人own,下次例会的时候检查执行情况。

QA内部showcase

在每个发布周期,在QA们做一次showcase,共享组内新开发功能特性。这样不仅锻炼了QA做好showcase的能力,同时也给其他团队QA共享了业务功能信息。

这两项实践以来,大家感觉到的收益还是蛮大的,除了知识、信息共享之外,也增进了QA间的相互了解,对于大家一起合作带来很大的帮助。

当然,除了这种具体的实践,更重要的是大家都有一颗愿意分享的心。随着例会和内部showcase的开展,QA们共享信息的意识得到了加强,日常工作中遇到某种情况觉得其他团队需要知道的就会主动分享出来。

大团队带来的挑战不是那么轻松容易解决,关于如何能高效协作,我们也还在继续摸索中。

不知道您所在团队是否也面临如此挑战?是否愿意和我们大家一起分享分享呢?

神圣的QA——写给应届毕业生

你有没有过下面的经历:

  • 在谷歌浏览器输入一个网址,出来一个错误提示:“不支持当前浏览器,请用IE访问”…
  • 换成IE,重新打开该网站,输入用户信息注册一个新用户,随后收到一封注册成功邮件,里边直接包含刚刚注册的密码…
  • 用注册的用户名密码登录进去,又不知道所需要的功能入口在哪里…
  • 翻遍了一层又一层的菜单,终于找到了入口,进去打开的是一个列表,足足等了2分钟才加载完成…
  • 从列表中找到自己需要的那个信息,点击“查看详情”,却显示一堆乱码…
这么多问题 :(

一次性碰到上面的各种当然属于极端现象,但我敢说,你一定碰到过其中的问题不止一次,而且碰到了一定很郁闷。这些都是软件缺陷,分别是兼容性、安全性、易用性、性能和功能方面的缺陷,一旦出现将会给企业和用户带来不同严重程度的影响。

这种糟糕的体验有没有使你产生想去优化的冲动?你是否想知道如何帮助软件开发团队开发出缺陷更少的软件产品?如果你的回答是肯定的,那么请跟我一起来做QA吧:)

QA是什么?

狭义的理解就是软件测试,软件测试工程师常被称为QA;广义上,QA就是在软件开发过程中做好软件质量分析和保证的人员。

QA的职责有哪些?

QA的职责

下面结合一个简单的例子说明QA的职责:生产杯子。

1. 理解和澄清业务需求

需求是软件开发的源头,需求的正确性、合理性对软件开发的质量有着至关重要的作用。QA的一个很重要的职责就是澄清需求、验证需求合理性,并且帮助团队一致理解需求。

需求包括功能需求,也包括各种非功能需求:性能、安全、易用性、兼容性等。所谓理解和澄清业务需求,就是需要把业务相关的功能和非功能需求都搞清楚了。

对于生产杯子的例子,QA需要搞清楚杯子的功能有哪些:普通的盛水、加热、保温、带吸管等等。杯子的功能可能还远不止这些,这就需要发散性思维,去挖掘可能得用途并进行确认、测试。除了功能需求以外,还有要考虑的非功能需求可能有:材质耐热性、耐摔性、跟各种液体的兼容性、安全性(是否有毒?是否可以砸伤人?)……

注意

需求的澄清是个过程,并不是在开始开发和测试之前要搞清楚所有的需求(这也是不可能的),同时可以在开发和测试过程中不断去澄清需求、优化业务流程。

2. 制定策略并设计测试

澄清了需求,还得知道怎么去验证软件产品是否满足了需求,这就需要制定测试策略,并根据策略设计测试。大概说来,需要确定测试范围、测试阶段,覆盖要求的测试范围都需要什么类型的测试(功能与非功能等),在每个阶段采用什么测试方法,手动测试和自动化测试的分配比例,如何设计手动和自动化测试的测试用例,用什么工具实现功能、性能和安全测试的自动化等。

对于杯子来说,确定需求之后,针对每一项需求指标需要确认可能采取的不同测试方法,需要考虑如何测试盛水和加热功能、如何测试耐摔性(直接摔吗?)、以及如何测试安全性等等。

可以参考测试四象限测试金字塔等模型来制定测试策略,并根据产品发布周期制定具体的测试计划、设计测试内容。

注意

设计测试,不仅是指设计测试用例。
四象限和金字塔只是个参考,不可以生搬硬套,而且有些内容稍有争议,但参考价值还是很大的。

3. 执行和实现测试

根据制定的测试策略和测试计划、设计好的测试用例,执行手动的验收测试和探索式测试等,实现和执行功能和非功能的自动化测试,统计和生成测试结果报告。

对于生产的杯子,根据设计的测试方案对产品(半成品)进行测试,可能的方式有:往里加水,直接摔到地板上,加热至100摄氏度,往里注入硫酸等。测试之后,统计和生成杯子的测试结果报告,内容包括但不限于测试样品集、测试方法、测试结果、成功率等。

4. 缺陷管理

测试之后,必然会发现很多的缺陷,对这些缺陷进行有效的管理是QA们一个非常重要的职责之一。缺陷管理包括以下内容:

  • 记录缺陷
    发现缺陷以后,QA需要尽自己所能去调查缺陷,收集所有跟缺陷相关的信息,包括不限于出现的环境(操作系统、浏览器和不同的测试环境等)、重现步骤、屏幕截图、日志等,并将这些信息简单清晰的记录下来。
  • 确定严重性和优先级
    严重性是指缺陷发生对用户所产生影响的严重程度,优先级是指需要修复的紧急程度,通常需要结合严重性和发布计划等来确定。新QA往往比较容易混淆这两个概念,注意它们是有区别的,优先级高的严重性不一定高,而严重性高的往往优先级比较高。具体需要根据产品和项目实际情况来确定。
  • 分析和跟踪缺陷
    开发人员修复缺陷之后,QA需要测试和验证缺陷,很多时候缺陷被验证之后就没人管了,但缺陷的生命周期并没有结束,后面还有非常重要的分析和跟踪阶段。在这个阶段,QA要分析缺陷产生的原因,影响的功能模块,过去一段时间以来的发展趋势等,根据这些分析结果制定下一阶段避免和减少同样缺陷产生所需要采取的行动措施,并且跟踪行动执行的详细情况。
注意

缺陷分析是非常重要的一个环节,但却很容易被忽略。关于缺陷管理的更多详细内容请参考我的另一篇文章《软件缺陷的有效管理》

再来看看杯子的例子,执行一番测试之后,可能发现如下缺陷:

  1. 容积为100毫升的量杯只能盛水80毫升
  2. 杯子表面不够光滑但不影响使用
  3. 清水倒进去水变成酸的了

第一个是严重的功能缺陷,第二个属于UI问题,第三个可能是一个非常严重的安全性问题。QA需要将这些缺陷报告,并根据严重性和产品流程等来安排优先级,督促开发人员及时修复高优先级的缺陷。缺陷修复并重新测试没问题之后,要分析统计,找出产生缺陷的环节,并采取措施防止下一批杯子出现同样的问题。

5. 质量反馈和风险意识

软件产品的质量不是QA这一个角色能保证的,而是需要整个开发团队所有人员齐心协力,共同为质量负责。QA作为质量分析保证的主力军,对产品质量需要有更清晰的认识,及时识别质量风险,并反馈给整个团队。

将质量相关因素可视化出来,是反馈给团队的较为有效的方式。质量可视化包括但不限于cycle time、自动化测试覆盖率、缺陷分析报告、错误日志分析、网站分析工具统计报告、性能监控数据、安全扫描结果、用户反馈、产品环境下的缺陷统计等,可以根据项目和产品具体情况具体定义。

定期或者不定期的把这些可视化结果反馈给团队,有助于形成团队对质量的统一认识,发挥团队每个成员对于质量保证的主观能动性,从而一起制定和调整下一阶段的质量保证策略。

测试了一批杯子之后,将杯子的质量相关情况反馈给团队,内容可能是:

  • 最近这批杯子出现的缺陷明显比上一批少,可以鼓励团队再接再厉;
  • 这批杯子出现了很多严重缺陷,那么就需要组织团队一起讨论问题根源,考虑采取措施防止问题重复出现;
  • 某一批杯子等待很久才可测,需要分析原因,采取改进行动;
  • 这一批杯子生产效率明显比以前有提高,同样可以确认效率提高的原因,后续可以以此为参考持续改进和提高。

QA的必备技能要求

硬技能之扎实的计算机基础

软件测试的概念虽然已经出现多年,但QA或者软件测试工程师还是被很多人误认为就是简单的点击应用程序进行测试,是一项没有技术含量的工作。其实,从前面对QA职责的描述,大家可以看到,QA的技能要求还是蛮高的,其中非常关键的一项就是具备扎实的计算机基础,具备基本的编码能力和数据库操作能力。

只有了解系统的工作原理,才能更好的去验证系统的完备性,发现问题才能更快更有效的初步定位。因此,下次有人问你为啥选择软件测试行业,千万别说是因为自己技术不行,那样会被鄙视的。

各项软技能

从QA的职责要求可以看出,做好QA还需要多方面的软技能:

  • 快速理解业务的能力:通常丰富的领域知识和快速学习新事物的能力可以帮助快速理解业务。
  • 分析能力和定位问题的能力:执行测试和定位缺陷的过程中,这种能力非常重要。
  • 良好的沟通表达能力,包括口头和书面沟通:QA需要跟客户、需求人员、开发人员等不同角色沟通以更好的完成工作,良好的沟通将会事半功倍。
  • 踏实、认真、细心:每一个测试、每一个缺陷都需要认真的对待,容不得半点浮躁,这些技能无需细说。

当然,除此之外,能在QA职业道路上有良好的发展,极其重要的一点是对软件质量相关工作有浓厚的兴趣。

写在最后

QA在一个软件开发团队,能与需求人员一起分析需求,能与开发人员一起编写测试,能给团队和客户详细展示系统功能,还能更新整个产品/项目的质量状态,是比PM更为了解产品/项目的人,听起来就很厉害,对不对?

是的,QA就是这么神圣的工作!你心动了吗?

敏捷实践Showcase的七宗罪

Showcase介绍

Showcase

Showcase就是开发团队把开发好的功能给客户的Product Owner(以下简称PO)等业务相关人员演示,以获取他们对所开发系统的反馈,是敏捷开发流程中的一个实践,一般频率是一个迭代一次,也可以根据项目具体情况做调整。Showcase是做功能演示,同时也是展示开发团队面貌的时刻,其重要性不言而喻,但据我经历的项目,总能看到一些不是很理想的地方。

Showcase之七宗罪

Showcase七宗罪

1. 准备工作没做好

所有人就位,准备开始showcase的时候,突然发现环境没有ready,连不上了!

好不容易把环境弄好了,开始showcase,可是数据又没有ready,还要临时创建,花了大半天时间(创建、准备数据)才终于show到了真正要演示的功能……

主讲人手忙脚乱,而其他人都要在这种忙乱中等待,浪费了很多宝贵的时间,尤其是对于PO那些重要人物来说。

###### 正确做法:充分做好准备工作

确定要做showcase的功能后,需要提前把以下事情提前做好:

  • 从业务的角度把整个要演示的功能尽可能的串起来,准备好showcase演示的步骤;
  • 演示数据也需要准备好,showcase的时候可以直接使用,只需要操作所演示功能部分,不需要临场创建准备数据;
  • 演示环境要提前准备好,包括部署好需要演示的应用程序版本,而且要告诉团队不要破坏了准备好的环境。

2. 没有上下文铺垫

着急忙慌的准备好一切之后,就开始页面操作了,也不先介绍一下要演示功能的来龙去脉,不说一下这个功能是干嘛的。这样,那些日理万机的PO等业务人员,他们很有可能没见过这个系统功能的样子,容易被搞得云里雾里、不知所云……

###### 正确做法:开始演示前要先介绍上下文

根据自己对所演示功能的理解,先介绍该功能的业务价值,满足了用户的什么业务需求,让在座的各位业务人员能够更容易理解后续showcase的内容。

3. 逐条过AC

Showcase的过程就是按照用户故事(story)的验收标准(AC, Acceptance Criteria)一条一条的过一遍,没有连贯性,这样的演示过程很难让观众把每条AC跟整体的系统特性、真正的业务场景联系起来,容易迷失,因此,常常会有演示完了一个story,而客户却问这是实现了什么业务需求……

正确做法:以功能为单位演示

不要一个一个用户故事演示,而是将整个功能串起来,最好定义出一个一个的业务场景演示给客户看,并且尽量使用业务语言描述。这样,让客户的业务人员感觉更有亲切感,看到开发团队的人员能够用业务语言描述和演示,他们一定会留下好的印象。

4. 企图覆盖所有路径

系统功能通常会有不同路径实现的是同一个相同或类似的功能,比如一个上传文件的功能有多个入口,但到达的上传文件页面是相似的。有人在演示这个文件上传功能的时候,企图把所有入口进去的文件上传都要完整演示一遍,到后来根本没有观众愿意关注,都在私下讨论了,有时也会有客户业务人员直接出来制止继续下去。

正确做法:只演示最关键路径

对于多个路径实现相同或相似功能的时候,对其中一条最复杂/重要的路径进行详细演示,其他路径提到即可,并指出其他路径不同的地方,不需要一一演示,以节省时间。

5. 过多提及跟演示功能无关内容

有人天生能聊,showcase的时候也是喜欢啰啰嗦嗦的说一大堆,经常会提及一些跟正在演示的功能无关的东西,或者提及团队采用的技术方案等业务人员不感兴趣的内容,导致showcase过程不能按时结束,甚至有些重要的反馈反而没有收集到。

正确做法:只提及要演示的功能

有时候一个showcase周期内可能开发了一个主要的功能,还有一些小的feedback的改动等,这时候showcase可以考虑只演示最主要的功能,那些小的feedback就不需要show了,也不要提及任何还未完成的功能模块,而且对于团队正在开发的技术卡或者还不成熟的技术方案等,一定不要提及,因为对方是业务人员,不会对技术相关内容感兴趣。

6. 认为showcase仅仅是BA或QA的事情

业务分析师(BA, Business Analyst)和质量分析师(QA, Quality Analyst)通常是团队跟业务打交道最多的,是最了解业务的,而showcase就是给客户的业务团队做系统演示,于是团队其他角色就会有人觉得showcase仅仅是BA或者QA的事情,跟自己无关,也不关注。

正确做法:人人都可以showcase

Showcase不是某个角色独占的,团队所有人只要对业务、对要演示的系统功能足够了解就可以负责showcase,通常可以采用团队不同人员轮换负责showcase方式,以增加团队成员在客户面前的曝光率,同时也能增强团队不同角色人员熟悉系统、熟悉业务的意识。另外,就算不是主导showcase,团队人员也可以尽量的多参加showcase会议,这是一个了解系统、听取客户反馈的非常好的机会。

7. 不熟悉的新人负责showcase

既然showcase不仅是BA或QA的事情,常常也会有其他角色来参与负责这件事情。从团队能力建设的角度考虑,PM有时候会让一些比较junior的同事或者新来不久还没有好好了解系统的同事来做showcase,结果就是演示过程非常生硬,甚至会有很多说不清楚的部分,而在一旁听着的BA/QA着急的只好上来帮忙解释。

正确做法:showcase前先充分了解系统和业务

虽然人人可以showcase,不建议利用给不熟悉的新人提供showcase的机会来提高能力,如果是要给新人锻炼机会,可以让新人在结对编程、Story Kickoff、Desk Check的时候多多的主导,等到对系统和业务有了一定的了解再给客户展示比较好;或者新人非常有意愿直接主导showcase,那么一定要在演示前做好对系统和业务的充分了解,以能应付和解答客户的挑战和疑问。

总结

 专业+高效

前面关于showcase的正确做法都是围绕两个词“专业(Professional)”和“高效(Efficient)”展开的,showcase的目标观众是客户的PO等业务人员,他们是决定是否认可开发团队所开发功能的至关重要的人物,我们在showcase过程中表现出专业性和高效率非常重要。因此,只要记住这两个词,并严格遵循,showcase一定能做好。

产品环境下的QA

2015年11月ThoughtWorks发布的技术雷达提到一个新的主题——产品环境下的QA(QA in Production),2016年4月再次提到。这个主题第一次出现在技术雷达,就深深的吸引了我,当时我就给测试团队成员转发了这个内容,但同时脑子里却产生这样一系列的疑问:

  • 产品环境下的QA可以做什么呢?有什么挑战,又有哪些好处?
  • 它跟类产品环境的QA有何区别,是否就是类产品环境QA方法的延伸?
  • 产品环境有运维支持团队(Ops),产品环境下的QA跟Ops所做的事情又有什么区别与联系?

带着这些疑问,结合项目上的一系列实践,于是有了本文。

一个产品环境Bug的解决办法

先来跟大家分享一个产品环境下的Bug:

一个在线订购葡萄酒的系统,订购流程相对复杂,下单过程中后台会有随机的失败,系统采取的措施是重试,就是说顾客下单后,后台如果有错误就会不停的重试,直到成功,这个过程对顾客是不可见的。这听起来没什么问题,用户体验似乎也不错。

后来有个新版本上线了,顾客下单后还是会有随机失败,系统依然不停的重试,但这次不一样的是有的随机失败,下单却能够成功,这样就导致用户虽然只订购一箱葡萄酒,由于后台的多次重试都成功了,用户最终拿到的可能是好几百箱葡萄酒。

这是一个非常严重且昂贵的Bug!对于这样的问题,作为QA,你能想到的解决办法有哪些?

瀑布式QA流程

瀑布式软件开发模式下,测试是计划驱动的,基本是根据需求文档进行验证,测试的目的就是找到尽可能多的bug,而且测试阶段处于开发阶段结束之后的一个相对独立的阶段,测试结束之后发布产品到产品环境。基本流程如下:

瀑布式QA流程

对于上述葡萄酒订购系统的Bug,通常的办法就是加强在测试阶段的测试保证,除了验证系统功能跟需求文档的一致性以外,还可以增加一些ad hoc测试,确保发布到产品环境的系统尽量的稳定。

敏捷QA流程

敏捷测试则提倡尽早测试、频繁测试,QA要从需求分析阶段就开始介入,QA参与从需求到发布的整个生命周期中各个阶段。在整个QA的过程中,会依据敏捷测试象限,在不同阶段采取不同的测试;还会根据测试金字塔的分层指导,加强自动化测试,制定有利于项目质量保证的测试策略,同时也会做探索性测试,尽量去发现更多不易发现的缺陷。敏捷QA的流程如下:

敏捷QA流程

对于葡萄酒订购系统的bug,处理方式也无非就是加强上线前各个阶段的测试,提高发布到产品环境的产品质量。

除此之外,我们还有什么处理办法呢?

上面两种开发模式下,QA的重点都是放在发布前的类产品环境的质量保证上,而较少考虑产品环境的系统质量。随着敏捷开发和持续交付的出现,QA角色逐渐转变到需要分析软件产品在产品环境下的质量。这需要引入产品系统的监控, 制定检测紧急错误的警报条件,持续质量问题的确定以及找出在产品环境下使用的度量以保证这种方式可行。

回到前面葡萄酒订购系统的那个Bug,如果在产品环境下设置监控预警,对于一个订单购买葡萄酒数量异常的情况进行监控,将能及时发现bug,并且比较容易在损失发生之前及时阻止产生更严重的后果。这就是产品环境下的QA内容之一!

产品环境的特点

为了更好的实践产品环境下的QA,先来分析下产品环境有哪些特点:

1. 真实、不可破坏

产品环境都是真实用户在使用,是真正的支持企业业务运转的系统,不可以随意在产品环境去做测试,尤其是破坏性的测试。

2. 基础设施差异

产品环境往往有着比类产品环境要复杂和健全的基础设施,可能会出现类产品环境不能预测到的缺陷和异常。

3. 系统复杂度

产品环境需要与多个不同的系统集成,系统复杂度会比类产品环境高很多,这种复杂的系统集成很有可能导致一些意外的情况出现。

4. 数据复杂度

产品环境的数据量和数据复杂度也是类产品环境无法比拟的,通常都不是一个数量级的数据,容易引发性能问题、或者一些复杂的数据组合导致的问题。

5. 用户行为千奇百怪

产品环境的用户分布广泛,使用习惯各种各样,导致用户行为千奇百怪,某些使用行为可能就会产生意想不到的问题。

6. 访问受限

产品环境由于是真实业务线上的系统,对安全性和稳定性要求更高,服务器的通常不是所有QA可以随便访问的,这种访问受限的情况对于产品环境的一些缺陷的排查带来了很大的不便。

7. 真实的用户反馈

真实用户在产品环境使用,能够提出一些真实而重要的反馈,但是开发团队往往不能直接接触终端用户,QA也就没有办法获得第一手的用户反馈,这些反馈常常需要通过支持团队的转述。

产品环境的特点

产品环境的这些特点决定了QA在产品环境不是想做什么就能做什么的,原来类产品环境那套质量保证理论和方法都行不通了。

产品环境下的QA有这么多挑战,听起来是不是很沮丧?不要着急,针对产品环境独有的特点,一定能找到相应的解决方案。接下来,咱们一起来看看产品环境下(不仅是QA)可以做什么。

产品环境下可以做什么

一、监控预警

前面讲到不能随便去操作产品环境下的系统对其进行测试,但是可以通过监控的方式去获得我们需要的信息,对异常情况进行预警。提到监控预警,不得不提大家都了解或者至少听说过的日志和网站分析工具,这两者都是做好产品环境下的QA非常有帮助的工具。

监控预警
日志

日志就像是飞机上的黑匣子,可以记录系统运行的各种信息,包括错误、异常和失败等。一旦程序出现问题,记录的这些信息就可以用来分析问题的原因;同时可以利用记录的日志设置好预警,提前预测系统可能出现的问题。产品环境下日志所提供的监控和预警信息,将有利于:

  • 阻止不良后果,避免大的损失:前面提到的葡萄酒订购系统就是一个很好的例子;
  • 发现潜在的性能问题:通过对日志进行分析,可能发现还没暴露出来的性能问题,提前修复;
  • 指导类产品环境的测试:通过产品环境下日志的分析,可以看出哪些功能易出什么样的错误,从而相应调整测试策略,加强类产品环境的相关功能的测试。
网站分析工具

网站分析工具根据具体工具不同,所能记录信息也有差异,但基本都可以记录如下信息:

  • 用户使用的操作系统、浏览器等信息
  • 用户行为习惯,包括使用的时间、关键路径、关键业务流程等
  • 用户所在地区、语言等区域信息
  • 用户访问量,请求的响应时间,网站性能等

利用网站分析工具收集到的以上数据,可以帮助我们调整类产品环境的测试侧重点,指导类产品环境的测试;根据用户行为习惯等信息,还可以帮助优化产品业务价值。

二、用户反馈

介绍产品环境特点的时候提到一点就是产品环境能够收到真实的用户反馈,这是非常有价值的,要做好产品环境下的QA一定要利用这些反馈。由于用户行为和习惯的千奇百怪,用户提供的反馈也可能是各种各样的,为了更好的利用它们,需要一个严格的Triage的过程,对所有反馈进行分类并相应处理。用户反馈,可以总结为下面几类:

用户反馈
缺陷

用户在使用过程中,系统所出现的问题,并且能够稳定重现的,我们定义为缺陷,缺陷通常会影响到功能的使用,是需要修复的,根据优先级和严重程度,安排相应的修复计划并对其进行修复,同时还需要对修复的缺陷增加(自动化)测试,以防被再次破坏。

除了能够稳定重现的缺陷,有时候还会有一些随机的失败(比如前面提到的葡萄酒订购系统的bug)或者难以重现的问题,这类问题很难找到原因,但是又给用户带来很大的不爽。其实,它们通常也是一些缺陷引起的,只是根源可能隐藏的比较深,对于这种问题的处理办法就是前面部分提到的可以添加日志对相关功能进行监控和预警,利用日志协助找到问题根源并进行修复。

抱怨

用户在使用系统过程中由于行为习惯、网络环境等差异,总会有各种抱怨,一般以非功能性的问题居多,比如易用性、性能、可维护性、可扩展性等,当然也有可能是某个功能设计的不能满足真实的用户需求。需要对所有抱怨进行分类,确定是非功能的缺陷,还是新的需求。用户的抱怨有可能千奇百怪,不是所有的都能满足,需要根据分类定义优先级,确定哪些是需要改进和修复,从而采取相应的措施。

建议

除了反馈问题和提出抱怨,用户也会对系统使用方面提一些建议。但一般用户很难提出好的建议,要想收集到有价值的信息,需要提前设计好问卷进行问卷调查,有针对性的去收集;或者对一些重要用户进行访谈,或者发布一个简单的新功能收集用户的使用建议等。然后对收集到的建议进行分析,确定可行性,并将可行的建议应用到后续的系统和业务流程的改进中。

利用用户反馈,改进系统功能,可以优化业务价值,扩大产品的市场影响力,提高企业的竞争力。常被用来收集用户反馈的实践有:

  • Beta测试:很多有前瞻性的网站或应用会发布新功能给特定用户组(Beta用户),收集用户使用新功能的统计数据;
  • AB测试:同时发布两个不同版本的系统到产品环境,并将用户引导到两个版本,统计使用每个版本的用户数据;
  • Observed Requirement:发布一个简单的功能,或者发布一个MVP版本,观察用户使用情况,从而引出并收集到用户的真实需求。

监控预警、收集和分析用户反馈并不是QA能独立完成的,需要与不同角色协作,QA在整个过程中主要充当分析者和协调者的角色,对产品环境下的质量保证工作起到至关重要的作用:

  1. 跟DEV一起讨论监控标准,把日志标准化的要求融入到软件开发流程中,确保日志能够记录到真正需要记录的信息。
  2. 跟运维团队一起分析收集到的统计数据,指导和优化各个阶段的测试,以预防和减少系统在产品环境下的缺陷。
  3. 跟业务分析人员一起分析和梳理从产品环境收集到的需求相关的反馈,提炼出合理的需求,优化业务价值。
QA与不同角色协作

产品环境下的QA在项目上的实践

我所在的项目是一个离岸交付项目,采用的是敏捷开发模式,四周一次发布到产品环境,开发的系统包括一个内部员工使用系统和一个外部用户使用的网站,用户遍及全球,项目整个已经持续了七年有余,产品环境具备前面所描述的所有特点,并且产品环境每日的错误日志达到几千条。正是由于错误日志的数量到了一个不能忍的程度,产品环境引起了各方的关注,也使得产品环境下的QA迎来了试点的最佳时机。产品环境下的QA在我们项目上的实践主要是三部分内容:日志分析和优化、Google Analytics数据分析、用户反馈的收集和分析,下面逐个介绍。

日志分析和优化

既然错误日志那么多,首当其冲就是从这些错误日志下手。项目使用的日志分析工具是Splunk,这个工具功能强大、使用方便,关于工具的详细信息可以参考官网。下图所示为使用Splunk通过指定条件搜索日志文件得到的结果页面,结果集里四条类似乱码的东西就是代表有四种类型的错误日志,每种错误出现的数量和百分比都有统计,点击每条结果可以查看详细的错误日志信息。

Splunk日志分析

关于日志的分析和优化,我们在项目上做了如下工作:

1. 分析产品环境的错误日志

每天会有专人负责错误日志的分析,找出其中的优先级高的问题给团队修复。QA会协助重现、跟踪并负责测试这些重要的需要修复的问题,通过对错误日志的分析,QA可以大概的统计出哪些功能特性比较容易产生错误,在接下来的类产品环境的测试中要重点关注。
另外,对于某些功能由于测试环境的数据等局限性,担心部署到产品环境会产生错误或者有性能问题,一般上线后会着重关注这样的功能,除了日常的监控分析之外,还要单独对该功能的日志进行检查,以防产生严重问题。

2. 监控测试环境的错误日志

把产品环境错误日志的分析方法应用于测试环境,对测试环境的错误日志进行监控,尽量把环境无关由功能引起的错误找出来,尽早修复,不让其流落到产品环境。据不完全统计,最近两三个月通过这种方式发现并修复了好几个潜在的Bug。

3. 利用日志监控不同功能的性能

Ops在Splunk里设置有专门的统计和监控系统性能的Dashboard,QA会定期从里边拿出潜在的存在性能问题的功能模块,创建对应的任务卡由开发团队来做性能调优。

4. 日志记录标准化

通过对产品环境错误日志的分析,发现现有日志记录存在如下问题:

  • 存储位置不统一,有些日志没有办法通过Splunk统计分析,造成分析成本的增加;
  • 记录格式不一致,有些日志虽然可以通过Splunk看到,但是没有记录很有用的信息,比如没有记录错误发生时候的一些有意义的message,或者是Post请求没有记录输入参数,导致排查错误日志的工作增加了难度;
  • 日志级别定义混乱,有些没有到达错误级别(error)的日志也记成了错误(error)日志,这也是错误日志数量大的原因之一。

为了让日志分析更轻松、让日志更全面的记录系统的各种情况,针对上面的问题,团队讨论并达成共识:

  • 将日志输出到各个服务器的同一个路径;
  • 统一日志记录格式,并且尽量记录更全面的信息帮助后期的日志分析;
  • 清晰定义各个日志级别(Debug,Info,Warning,Error,Critical,Fatal),将已有的误记成错误的日志降低到正确的级别,对于新功能则严格按照所定义级别记录日志;
  • QA在用户故事(Story)的开发机验收(Dev-box Testing or Desk Check)阶段负责跟开发人员确认相关日志记录是否符合标准,并且通过测试环境的日志监控可以及时验证新功能的日志记录情况。

Google Analytics数据分析

Google Analytics(以下简称GA)是项目用来统计网站使用情况的工具,从GA上可以获取很多有价值的信息,对这些信息的分析是我们实践的产品环境下QA的另一块内容,具体做了下面几项工作:

1. 操作系统和浏览器使用情况分析

根据GA数据统计分析出用户使用的操作系统和浏览器分布情况,从而相应的调整QA用来测试的操作系统和浏览器,尽量让测试环境跟真实用户更接近。比如,前两年客户内部员工使用的浏览器最多的是IE9,那么我们QA的测试也是主要关注IE9,而今年变成了IE11,我们重点关注的浏览器也相应调整为IE11(当然,鉴于IE9的特殊性——容易出问题,只要还有用户使用,我们还是需要关注),而对于没有用户使用的Firefox,我们则不用来测试。

2. 分析QA测试跟用户真实行为的差异,及时调整测试根据

GA上用户访问的路径可以发现我们QA的测试跟一些真实用户使用习惯的差异,这样如果按照我们通常的路径去测试,可能有些问题难以在测试阶段发现。比如,QA在测试环境通常打开“工作记录”的方式是这样的:

QA测试路径

而我们从GA上发现真实用户使用过程中,打开“工作记录”最多的路径是这样的:

用户使用路径

发现了这种差异,QA就要在测试时候做相应的调整,让测试更接近用户的行为习惯。

3. 提炼关键业务场景,增加测试覆盖

一个开发好几年的系统,其功能必然是比较复杂的,由于自动化测试覆盖率不是很理想,过去回归测试需要的投入比较大,而且由于功能相对复杂,又不是很清楚哪些功能对用户来说最为重要,测试很难做到有效覆盖。这种情况对于人员比例低下的敏捷团队QA来说,是一件非常有挑战的事情,通常QA们在发布前忙得不行。利用GA的数据结合客户业务人员对系统各功能使用情况的介绍,我们提炼出来系统最为关键的一些业务场景,并且尽量分层(参考测试金字塔)实现自动化测试覆盖,从而不需要花费太多的人力去做回归测试,同样可以保证主要的业务流程不至于被破坏,而QA则可以有更多的时间和精力去做探索性测试等更有价值的事情。

4. 发现用户较少使用的功能,优化业务流程

关键场景就是用户使用频率较高的功能,类似的,我们还可以通过GA发现一些用户较少使用的功能,这可能的原因是不符合用户真实行为习惯,喜欢用其他路径去完成同样的事情,或者不符合真实业务需求,也就是说真实的业务环境下根本没有要用到这个功能的地方。对于这种功能,首先从QA角度来讲,我们的测试基本不需要太多去关注,如果有相关功能的缺陷,它的优先级也很低很低;另外,可以跟业务分析人员一起分析下原因,在后续的功能开发过程中可以作为借鉴,从而优化业务流程。

5. 分析用户地区分布和使用时间段分布,合理安排定时任务运行时间

系统用户遍及全球,使用时间段分布也就变得复杂,为了不影响正常使用,有些事情是需要尽量在系统没人使用的时候去做的,比如统计某类数据需要定时执行SQL脚本等定时任务。通过GA上的数据,统计出哪个时间段是相对空闲的,在不影响真实业务的前提下,把一些资源消耗较大的任务安排在那个时候执行,合理分配资源以减轻服务器的负担。

6. 监控系统性能变化趋势,规避性能风险

QA定期查看网站平均访问时间,监控性能趋势,同时要重点关注那些访问非常慢的页面或功能,必要的时候创建性能缺陷卡,由开发人员来调查分析并修复或优化。

7. 确保GA能够统计到所有需要统计的功能

GA数据虽然很有用,但前提是正确记录了所需要统计的数据,所以在开发过程中要确保GA嵌入到了各个需要统计的功能或页面,QA在类产品环境测试的时候需要验证这一点。

下图为从GA拿到的浏览器分布情况和页面平均加载时间的一些数据:

GA统计数据

用户反馈的收集和分析

作为开发团队的我们基本是不能直接接触到系统终端用户的,直接接受反馈的是我们客户的Ops团队,QA主要通过下面几个途径去协助分析和梳理用户反馈:

1. 跟Ops和业务的定期沟通会议

QA会定期跟客户的Ops和业务人员沟通,了解用户对于现有系统的反馈,找出在测试中需要重视的功能特性,将类产品环境的测试关注点做出相应的调整。

2. 培训Ops人员

指导和协助客户Ops人员利用鱼骨图(Fishbone Diagram)的方法对收集到的用户反馈进行分析和分类,将分析结果跟现有的测试覆盖情况进行对比,找出测试过程的薄弱环节,并做出改进。比如,如果某个浏览器出现的bug比较多,而我们的测试则要加强该浏览器的关注;或者是因为不同用户权限导致的问题出现频率高,那就得在测试中注意覆盖不同用户角色的测试,反之则减弱不同用户的覆盖,主要测最常用的那类角色即可。

3. 调查和跟踪产品环境Bug

帮助重现和调查用户反馈过来的产品环境Bug,并负责跟踪修复和验证;对于难以重现的问题,则添加日志监控,通过分析收集到的日志信息找出问题根源,从而进行修复。

4. 协助梳理业务需求

系统要增加某个新功能的时候,客户Product Owner(以下简称PO)或其他业务人员跟用户会一起沟通该功能相关业务现有的使用习惯、使用场景,QA也会尽力参与这种会议,收集用户第一手需求信息,这些信息对于后期该业务功能开发时候的QA过程将非常有帮助。而还有些功能,PO可能一时也拿不定主意要做成什么样子,我们会发布MVP的版本给用户使用,QA协助业务人员分析用户使用后的反馈,梳理更具体的用户需求。

产品环境下的QA有什么特点

1. 不同于类产品环境的QA

产品环境的特点决定了产品环境下的QA是跟类产品环境的QA不同的,不是主动的去测试产品环境的系统,而是通过设置监控条件,收集用户使用系统的反馈,对反馈进行分析并改进,从而让产品质量获得提高。因此,产品环境下的QA并不是类产品环境QA活动的简单后延,它有着自己独特的特点。

2. 不能独立存在

产品环境下的QA所设置的监控标准是根据系统的行为特点和在类产品环境下的表现来定义的,产品环境下各项反馈的分析结果反过来又影响着类产品环境的QA过程,而且这两者是相辅相成的,只有形成了良性环路,才能把产品环境下的QA做好。

良性环路
3. 有别于Ops

产品环境设置监控预警和收集用户反馈不都是Ops团队可以做的事情吗?还要QA参与干什么?那是因为QA有着独特的思维模式和视角,QA的参与能够帮助更好的分析产品环境下收集到的各种反馈,并且结合对于系统的了解,能够将这些反馈更好的应用到日常的开发工作中。

这时候的QA带着QA和Ops的帽子,兼具QA和Ops的部分职责,类似于QAOps,不过现在都提倡不要有独立的DevOps,我们也不要独立的QAOps角色,只是让QA这个角色可做的事情得到了延伸和扩展而已,本质上还是QA。

产品环境下的QA与Ops
4. 跟APM的侧重点不同

可能有人会觉得产品环境下的QA跟APM有相似之处,那么这两者是不是一回事呢?

维基百科这样解释APM

“In the fields of information technology and systems management, application performance management (APM) is the monitoring and management of performance and availability of software applications. (在信息科技和系统管理领域,APM是对软件应用程序的性能和可用性的监控和管理。)”

APM更多的是从性能角度出发去管理和优化应用的可用性,可以发生在各个阶段,不一定是产品环境。产品环境下的QA是指在产品环境进行一系列的监控和数据收集,从系统功能、性能、易用性等多个方面进行优化,从而最终优化业务价值。因此,两者是不同的。

总结

  • 产品环境下的QA将QA的工作范围扩大到从需求到产品环境,增加了更多的反馈来源,跟持续交付结合,可以帮助持续提高产品质量、持续优化业务价值。
  • 产品环境下的QA给QA的工具箱添加了更多的工具,提供了更多评估和提高系统质量的选项,是QA们值得深入研究的话题。
  • 产品环境下的QA不能走的太远,必须先做好类产品环境的质量保证,并且仅适用于持续交付实践的比较好的组织,如果连类产品环境的质量保证都做不好,而就想着去做产品环境下的QA,那只能是舍本逐末、事倍功半。

软件测试新趋势

2015年11月,ThoughtWorks发布了新一期的技术雷达。技术雷达是以独特的形式记录ThoughtWorks技术顾问委员会对行业产生重大影响的技术趋势 讨论的结果,为从CIO到开发人员在内的各方利益相关者提供价值。这期雷达的技术趋势主要体现在:受到热捧的微服务相关技术,逐步成熟的以Docker为典型的容器化生态系统,备受企业和用户关注的信息安全问题。本文就从这几个新趋势来分析一下给软件测试带来了哪些影响。

自动化测试是王道

在这个快速变化发展的时代,任何一款产品想要在市场具备竞争力,必须能够快速适应和应对变化,要求产品开发过程具备快速持续的高质量交付能力。而要做到快速持续的高质量交付,自动化测试将必不可少。同时,自动化测试也不是用代码或者工具替代手工测试那么简单,有了新的特点和趋势:针对不同的产品开发技术框架有着不同的自动化技术支持,针对不同的业务模式需要不同的自动化测试方案,从而使得自动化测试有着更好的可读性、更低的实现成本、更高的运行效率和更有效的覆盖率。来自技术雷达的下列主题分别体现了自动化测试的这些特点:

– 针对微服务的消费端驱动的契约测试(Consumer-driven contract testing),有助于解决随着服务增多带来集成测试效率低和不稳定的问题。消费端驱动的契约测试是成熟的微服务测试策略中核心的组成部分。

– 专门用于测试和验证RESTful服务的工具REST-assured,它是一个Java DSL,使得为基于HTTP的RESTful服务编写测试变得更加简单。REST-assured支持不同类型的REST请求,并且可以验证请求从API返回的结果。它同时提供了JSON校验机制,用于验证返回的JSON数据是符合预期的。

– 安卓系统功能测试工具Espresso,其微小的内核API隐藏了复杂的实现细节,并帮助我们写出更简洁、快速、可靠 的测试。

– ThoughtWorks开源的轻量级跨平台测试自动化工具Gauge,支持用业务语言描述测试用例,支持不同的编程语言,支持所支持平台的并行执行。

– 用于针对UI的自动化测试构建页面描述对象的Ruby库Pageify,该工具关注于更快的执行测试以及代码的可读性,并可以很好的配合Webdriver或是Capybara使用。

– 专门用于iOS应用开发的开源行为驱动开发测试框架Quick,支持Swift、Objective-C,它和用来做测试验证的Nimble捆绑发布。Quick主要用于Swift和Objective-C程序行为的验证。它和rspec和jasmine具有相同的语法风格,基础环境很容易建立。Quick良好的结构和类型断言使得测试异步程序更加容易。Quick拥有现成的Swift和Objective-C规范文件模板,开发者只需4步,即可对应用进行快速测试。

工具很重要,设计不可少!自动化测试工具云集,但做自动化也不要冲动,需要重视以下几点:

– 综合考虑项目技术栈和人员能力,采用合适的框架来实现自动化;

– 结合测试金字塔和项目具体情况,考虑合适的测试分层,如果能够在底层测试覆盖的功能点一定不要放到上层的端到端测试来覆盖;

– 自动化测试用例设计需要考虑业务价值,尽量从用户真实使用的业务流程/业务场景来设计测试用例,让自动化优先覆盖到最关键的用户场景;

– 同等看待测试代码和开发代码,让其作为产品不可分割的一部分。

自动化测试

云技术、容器化和开源工具使得测试成本下降

测试环境的准备在过去是一个比较麻烦和昂贵的事情,很多组织由于没有条件准备多个测试环境,导致测试只能在有限的环境进行,从而可能遗漏一些非常重要的缺陷,测试的成本和代价很高。随着云技术的发展,多个测试环境不再需要大量昂贵的硬件设备来支持,加上以Docker为典范的容器技术生态系统也在逐步成长和成熟,创建和复制测试环境变得简单多了,成本大大的降低。技术雷达推荐的凤凰环境(Phoenix Environment),它能够以自动化的方式支持测试、开发、UAT和灾难恢复所需的新环境准备。这一技术由上期的评估环上升到了采用环,表明它已经得到了验证和认可,是可以放心使用的技术。

另一方面是大量开源工具的出现,这些工具往往都是轻量级的、简单易用,相对于那些重量级的昂贵的测试工具更容易被人们接受。测试工作有了这些开源工具的帮助,将更加全面、真实的覆盖到要测试的平台、环境和数据,将会加快测试速度、降低测试成本;更重要的一点,有了这些工具,让测试人员能够腾出更多的时间来做测试设计和探索性测试等更有意思的事情,使得测试工作变得更加有趣。新技术雷达提到的开源工具有:Mountebank、Postman、Browsersync、Hamms、Gor和ievms等。

– 在企业级应用中,对组件进行良好的测试至关重要,尤其是对于服务的分离和自动化部署这两个关系到微服务架构 是否成功的关键因素,我们更需要更合适的工具对其进行测试。Mountebank就是一个用于组件测试的轻量级测试工具,可以被用于对 HTTP、HTTPS、SMTP和TCP进行模拟(Mock)和打桩 (Stub)。

– Postman是一个在Chrome 中使用的REST客户端插件,通过Postman,你可以创建请求并且分析服务器端返回的信息。这个工具在开发新的 API或者实现对于已有API的客户端访问代码时非常有用。Postman支持OAuth1和OAuth2,并且对于返回的 JSON和XML数据都会进行排版。通过使用Postman,你可以查看你通过Postman之前发起过的请求,并且可以非常友好的编辑测试数据去测试API在不同请求下的返回。同时,虽然我们不鼓励录屏式的测试方法,但是Postman提供了一系列的拓展允许我们将它作为跑测试的工具。

– 随着网站应用所支持设备的增多, 花在跨设备测试上的代价也在不断增大。Browsersync能够通过同步多个移动设备或桌面浏览器上的手工浏览器测试来极大的降低跨浏览器测试的代价。通过提供命令行工具以及UI界面,Browsersync对CI构建非常友好,并且能够自动化像填写表单这样的重复任务。

– 在软件开发领域,盲目地假设网络总是可靠,服务器总是能够快速并正确的响应导致了许多失败的案例。Hamms可以模拟一个行为损坏的HTTP服务器,触发一系列的失败,包括连接失败,或者响应缓慢,或者畸形的响应,从而帮助我们更优雅的测试软件在处理异常时的反应。

– Gor可以实时捕获线上HTTP请求,并在测试环境中重放这些HTTP请求,以帮助我们使用到这些产品环境数据来持续测试我们的系统。 使用它之后可以大大提高我们在产品部署,配置修改或者基础架构变化时的信心。

– 尽管IE浏览器的使用量日益萎缩,但对很多产品而言IE浏览器 的用户群依然不可忽视,浏览器兼容性仍然需要测试。这对于 喜欢使用基于Unix的操作系统进行开发的人来说还是件麻烦事。为了帮助解决这个难题,ievms提供了实用的脚本来自动设置不同的Windows虚拟机镜像来测试从IE6到Microsoft Edge的各种版本浏览器。

测试成本降低

安全测试贯穿整个生命周期

“安全是每一个人的问题”!互联网安全漏洞频繁爆发,安全问题已经成为每个产品迫切需要关注和解决的问题,安全测试将需要贯穿于软件开发的整个生命周期。同时,给软件测试人员带来了更多的机遇和挑战,要求具备更多的安全相关知识(其中还包括更多的计算机基础知识),掌握已有的安全测试相关技术,从而在软件开发的各个阶段做好安全相关的分析和测试工作。尽管有些团队已经将安全跟整个开发实践结合起来,但培养每个人在每个阶段的安全意识还相当的重要,探索新的安全测试技术、方法还有很多空间。

安全测试贯穿软件生命周期

技术雷达上列出的安全测试相关的技术和工具有:Bug bounties、威胁建模(Threat Modelling)、ZAP和Sleepy Puppy。

– Bug bounties是一个安全漏洞举报奖励制度,越来越多的组织开始通过Bug bounties鼓励记录常见的安全相关的Bugs,帮助提高软件质量。

– 威胁建模(Thread modeling)是一组技术,主要从防御的角度出发,帮助理解和识别潜在的威胁。当把用户故事变为“邪恶用户故事”时,这样的做法可给予团队一个可控且高效的方法使他们的系统更加安全。

– ZED Attack Proxy (ZAP)是一个OWASP的项目,允许你以自动化的方式探测已有站点的安全漏洞。可以用来做定期的安全测试,或者集成到CD的Pipleline中提供一个持续的常规安全漏洞检测。使用ZAP这样的工具并不能替换掉对安全的仔细思考或者其他的系统测试,但是作为一个保证我们的系统更安全的工具,还是很值得添加到你的工具集里。

– Sleepy Puppy是Netflix公司近期开源的一款盲打XSS收集框架。当攻击者试图入侵第二层系统时,这个框架可用于测试目标程序的XSS漏洞。XSS是OWASP的Top10的安全威胁,Sleepy Puppy可以用来同时为几个应用完成自动安全扫描。它可以自定义盲打方式,简化了捕获,管理和跟踪XSS漏洞的过程。Sleepy Puppy还提供了API供ZAP之类的漏洞扫描工具集成,从而支持自动化安全扫描。

优化业务价值

大多数软件都是做项目的模式,在不同的档期内进行计划、实现和交付。敏捷开发极大的挑战了这种模式,通过在开发过程中各个阶段进行的分析和测试工作,持续的发现新的需求,使得需求更趋于合理化,更能体现业务价值。精益创业的技术,如观察需求的A/B测试,进一步削弱了这种心态。技术雷达推荐“产品优于项目(Product over project)”,认为大多数的软件开发工作应该遵循精益企业的引领,将自己定义为构建支持业务流程的产品。这样的产品并没有所谓的最终交付,更多的是一个探索如何更好的支持和优化业务流程的过程,只要业务依然有价值就会不断持续下去。

作为软件开发中的关键角色、负责软件测试的QA人员,通过从用户角度对软件的测试,结合自身对软件产品的了解,对优化业务价值将会起到举足轻重的作用。软件测试不仅是检验软件是否满足规定的需求或弄清预期结果与实际结果之间的差别的过程,还需要有意识的对需求进行持续的验证和优化,对业务的趋势和风险进行分析。如果能在开发过程中结合使用BDD(行为驱动开发)的思想,统一团队对需求的认识,利用团队的力量来优化业务将会达到事半功倍的效果。

传统方式下,QA的角色主要专注于保证软件产品在类产品环境下的质量。随着持续交付的出现,QA的角色逐渐转变到需要分析软件产品在产品环境下的质量。产品环境下的QA(QA in production),就是要求QA角色在做好产品上线前的质量保证工作前提下,做好软件产品在产品环境下的质量分析。具体做法有:

(一)引入产品系统的监控, 制定检测条件,找出产品环境下使用的质量度量。比如,利用网站分析工具收集用户使用应用程序的数据,分析数据量需求、产品的性能趋势、用户的地域特征、用户的行为习惯和产品在同类型产品市场的占有率等。

(二)收集产品环境下最终用户的反馈,对反馈进行分类分析。这些反馈可能有:

– 缺陷:需要进行优先级划分,确定是否需要修复;并且对这些缺陷进行根源分析,在以后的开发过程中尽量避免同类型的缺陷再次出现。

– 抱怨:对于抱怨需要分析其背后的原因,可能正是能够帮助我们改进和优化业务价值的好机会。

– 建议:一般用户可能难以提出高质量的建议,需要我们在收集反馈的时候下点功夫,有针对性的去收集。一旦收集到了建议,将是对业务价值优化非常有利的。

通过对产品环境下的软件质量进行分析,将有利于协助“产品优于项目”实践,帮助优化业务价值,做好企业产品的创新工作。需要注意的是,产品环境下的QA可能会导致有些组织走的太远而忽视产品上线前的质量保证,它只对那些已经执行并有一定程度持续交付实践的组织有价值。

总结

软件测试是一项技术工作,但软件测试领域的问题不仅仅是技术问题。随着自动化程度越来越高,不断有人怀疑QA存在的必要性,从前面的分析可以看到,新趋势给QA提出了更高的要求,带来了更多的机遇和挑战,相信好的QA是不可能简单的被取代的。

(此文发表于TW洞见InfoQ