测试——《微服务设计》读书笔记

    系列文章目录:html

    《微服务设计》读书笔记大纲git

 

一.测试象限(Brain Marick)github

      

 

二.测试金字塔(Mike Cohn)安全

    

    

      1.单元测试服务器

      一般只测试一个函数或方法调用,经过TDD或者基于属性而写的测试就属于这一类,在UnitTest中,咱们不会启动服务,对且对外部文件和网络链接的使用也颇有限,一般咱们须要大量的单元测试。网络

      

      单元测试是帮助开发人员,是面向技术而非业务的。并发

      2.服务测试函数

      对于包含多个服务的系统,一个服务测试只测试其中一个单独服务的功能。只测试一个单独的服务能够提升测试的隔离性,这样咱们能够更快地定位并解决问题,为了达到这种隔离性,咱们须要给全部的外部合做者打桩,以便只把服务自己保留在测试范围内。(打桩是指为被测服务的请求建立一些有预调响应的服务。)微服务

      

       对于每一位下游合做者,咱们都须要一个打桩服务,而后在运行服务测试的时候启动它们,在测试过程当中链接这些打桩服务,为了模仿真实的服务,咱们还须要配置打桩服务返回请求响应。例如,咱们能够配置积分帐户为不一样的客户返回不一样的预设积分。工具

      另外一种替换打桩有方式是mock。与打桩相比,mock还会进一步验证请求自己是否被正确调用,若是与指望请求不匹配,测试便会失败,过分使用mock会让测试变得脆弱。二者之间须要一些权衡。

      咱们可使用一些打桩的软件来协助咱们测试,如Mountebank等。

      3.UI测试(端到端测试)

      对于包含多个微服务的系统来讲,“端到端的测试”这个名称相比“UI测试”可能更适合,端到端测试会覆盖整个系统,这类测试一般用图形界面来模仿用户交互动做。这类的测试会覆盖大范围的产品代码,所以当它们经过时你会感受很好。

      

      由于端到端测试涉及到多个微服务,咱们能够用扇入模型来解决多个微服务同时开发,同时测试的问题。

      

      虽然扇入模型能够来解决一些难题,可是端到端测试仍然有着不少的缺点。

      首先,端到端测试很是脆弱。

      有时测试失败并非由于功能真的被破坏了,而是由其余一些缘由引发的,好比其余服务中止或者网络故障等,这些跟测试的功能自己没有关系。

      包含在测试中的服务数量越多,测试就会越脆弱,不肯定性也就越强。

      一个包括脆弱测试的测试套件每每成为Diane Vaughn所说的异常正常化的受害者,也就是说,随着时间的推移,咱们对事情出错变得习觉得常,并开始接受它们是正常的。

      Martin Flower在http://martinflower.com/articles/nonDeterminism.html中提议,在碰到脆弱的测试时应该马上记录下来,当不能当即修复时,须要把它们从测试套件中移除,而后就能够不受打扰地安心修复他们。修复时,看可否经过重写来避免被测代码运行在多个线程中,再看是否能让运行的环境更稳定,更好的办法是,看可否用不易出问题的小范围测试取代脆弱的端到端测试。

      单个微服务的测试能够由这个特性团队来维护。那么涉及到多个微服务的端到端测试该由谁负责?

      虽然这种责任分配方式还在探索当中,但将测试对全部人开放或者把这些测试交给专门的团队来维护都是错误的,前者可能会致使团队成员能够在无须对测试套件质量有任何理解的状况下随意添加测试,这会致使测试用例爆炸,有时致使测试没有真正的拥有者,当测试失败时,每一个人都认为这是别人的问题,而不在意测试是否经过;后者则会致使开发人员没有在第一时间获得本身代码的测试反馈,这会出现很大问题。一个可能的解决方案是,让各特性团队共享端到端测试套件的代码权,对测试套件联合负责。

      端到端的测试一般须要的时间最长,若是常常有与功能破坏无关的测试失败,这就是个灾难,这样即便真的是功能被破坏了,也须要花不少长时间才能发现,而此时你们已经转而作其余的事情了,切换大脑的上下文来修复测试是很痛苦的。

       咱们能够用Selenium Grid工具经过并行运行测试来改善缓慢的问题,可是长期的积累,测试用例愈来愈多,但咱们却不敢删除测试,而这多是端到端测试面临着管理、维护困难的局面。咱们应该改变咱们的端到端测试思路,把测试整个系统的重心放到少许核心的场景上来,把任何在这个核心场景以外的功能放到相互隔离的服务测试中覆盖。

      同时,人们容易有这样的想法:既然全部服务在这些版本下可以一块儿工做,为何不一块儿部署它们呢?若是接受了这个观念,慢慢的这成了常态,咱们就会丢弃微服务的主要优点之一,独立于其余服务单独部署一个服务的能力。不用很长时间,原本分享地很好的服务就会与其余服务纠缠得愈来愈紧密,最终系统杂乱无序,你必须同时部署多个服务。这很是糟糕。

      4.三种测试之间的权衡

      越靠近金字塔的顶端,测试覆盖的范围越大,同时咱们对被测后的功能也越有信心,缺点则是须要更长的时间运行测试,反馈周期也会变长,测试失败后很难定位哪一个功能被破坏;而靠近金字塔的底部,测试更快,反馈周期也会变短,测试失败后更容易定位破坏的功能和代码,CI也很短。通常来讲,顺着金字塔向下,下一层的测试数量要比上一层多一个数量级。

 

三.消费者驱动测试

      使用以前的端到端测试,咱们试图解决的关键问题是什么?是试图确保部署新的服务到生产环境后,变动不会破坏新服务的消费。有一种不须要用真正的消费者也能达到相同的目的,咱们可使用消费者驱动的契约(CDC)。当使用CDC时,咱们会定义服务的消费者的指望,这些指望最终会变成对生产者运行的测试代码,若是使用获得,CDC应该成为服务提供者CI的一部分,这样能够确保若是这些契约被破坏了,服务提供者没法部署。

      让咱们回头看一下前面图片中的例子,客户服务有两个独立的消费者:帮助台和Web客户端,咱们将建立两个测试集合(其实就是模拟消费者),每一个集合分别体现帮助台和Web客户端对客户服务的使用方式。由于这些CDC是对客户服务如何工做的指望,因此,客户服务自己的全部下游依赖均可以使用打桩,从测试范围来看,它与测试金字塔中的服务测试位于同一层,但侧重点不一样,这些测试重在消费者如何使用服务。

      Pack(https://github.com/realestate-com-au/pact )是一个消费者驱动的测试工具,开始时,消费者使用Ruby DSL来定义生产者的指望,而后启动本地一个mock服务器(之后就能够单独地来测试消费者),并对其运行这些指望来生成pact规范文件,pack规范文件是一个标准的JSON规范;在生产者这边,你可使用 JSON Pact规范来驱动对生产者API的调用,而后验证响应以测试消费者的规范是否被知足,由于生产者代码须要访问Pact文件,因此咱们这里采用JSON。

      Pack的JSON规范是由消费者生成的,该规范须要成为一个生产者可访问的构建物,你能够把它存储在CI/CD仓库或Pack Broker中。

      另外Pacto(https://github.com/thoughtworks/pacto )和janus(https://github.com/gga/janus )也是开源的消费契约测试工具。

 

四.线上测试

      在生产环境咱们也须要进行测试,咱们能够在高峰或请求来临以前进行测试,这样能够发现特定环境中的问题。

      1.冒烟测试

      咱们能够对生产环境进行冒烟测试,用来帮助咱们识别与环境有关的任何问题,咱们应该把冒烟测试加入到咱们的部署脚本中。

      2.蓝绿发布

      使用蓝绿发布时,咱们会部署两份软件,但只有一个接受真正的请求。咱们对新部署的版本运行一些测试,等测试没有问题时,咱们再切换生产负荷到新部署的版本,一般状况下,咱们会保留旧版本一小段时间,这样若是发生任何错误,可以快速恢复到旧的版本。这样能够下降风险,还能够大幅减小发布软件所须要的停机时间,咱们甚至能够达到零宕机部署。

      3.金丝雀发布

      金丝雀发布是指经过将部分流量引流到新部署的系统,来验证系统是否按预期执行,与蓝绿发布不一样,金丝雀发布过程当中,新旧版本共存的时间更长,并且常常会调整流量。

      当考虑使用金丝雀发布时,你须要选择是引导部分生产流量到金丝雀,仍是直接复制一份生产请求,若是你选择复制一份生产请求,而后引导师复制的请求至金丝雀,这样现行的版本和金丝雀版本将面对相同的请求,只是生产环境的请求是外部可见的,这样方便你们对新旧版本作比较,同时又避免金丝雀发布失败时影响客户的请求,但复制请求的工做可能会很复杂,尤为是在请求不幂等的状况下。

      4.灰度发布

      灰度发布是指在黑与白之间,可以平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,若是用户对B没有什么反对意见,那么逐步扩大范围,把全部用户都迁移到B上面来。灰度发布能够保证总体系统的稳定,在初始灰度的时候就能够发现、调整问题,以保证其影响度。

      这些部署技术的原则,无外乎说明:更快的从错误中修复比想方设法地防范错误更重要,固然这不是说防范错误不重要,而是由于错误不可避免。

 

五.非功能测试

      非功能测试包括一些服务延迟测试、并发量测试、负载量测试、安全性测试、性能测试等。微服务拆分以后,会致使一个功能引起多个微服务的协同工做,这样跨网络边界调用的次数明显增长了,所以性能测试也是一件很是重要的事。

 

参考

      《微服务设计》(Sam Newman 著 / 崔力强 张骏 译)

转载于:https://www.cnblogs.com/gudi/p/6683305.html