微服务测试的思考与实践

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

从微服务的概念能够看出它有以下好处:架构

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

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

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

测试策略的选择

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

(经典策略模型)微服务

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

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

(蜂巢模型)单元测试

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

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

(钻石模型)

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

项目的故事

测试策略的演进

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

(测试策略的演进)

最初单一用户系统、单体架构的时候,严格按照测试金字塔来组织各层的自动化测试。随着功能的扩展,大量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等技术,加强系统的反脆弱性,从中获益。

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

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

 2018年11月12日

相关文章
相关标签/搜索