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

一.测试象限(Brain Marick)

      

 

二.测试金字塔(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 著 / 崔力强 张骏 译)

相关文章: 

  • 微服务的概念——《微服务设计》读书笔记

  • 微服务架构师的职责——《微服务设计读书笔记》

  • 建模:确定服务的边界——《微服务设计》读书笔记

  • 微服务集成——《微服务设计》读书笔记

  • 服务的协作:服务间的消息传递——《微服务设计》读书笔记

  • 拆分:分解单块系统——《微服务设计》读书笔记

  • 部署:持续集成(CI)与持续交付(CD)——《微服务设计》读书笔记

原文地址:http://www.cnblogs.com/gudi/p/6683305.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React功能界面的组件化编码流程

功能界面的组件化编码流程(通用) 1.拆分组件: 拆分界面,抽取组件 2.实现静态组件: 使用组件实现静态页面效果 3.实现动态组件 3.1 动态显示初始化数据 3.1.1 数据类型 3.1.2 数据名称 3.1.2 保存在哪个组件? 3.2 交互(从绑定事件监听开始)

Java 多文件上传

转载自 Java 多文件上传 前台代码很简单&#xff1a; <input type"file" accept".zip" class"file-load" multiple"multiple" name"files"/> 后台代码&#xff1a; public boolean uploadFlow(RequestParam Mult…

MyKtv点歌系统前台主要功能实现,内附数据库脚本,可以直接运行

C#开发工具&#xff1a;Visual Studio 2012 数据库&#xff1a;Sql Server Windows版本&#xff1a;Win10 分辨率&#xff1a;1366*768 文章的最后有KTV点歌系统的前后台源码下载链接。 在正式写代码之前先看一下运行效果图&#xff0c;如果觉得这个是你需要的&#xff0c;那么…

Hibernate使用最新的MySQL8.+版本出现的问题!

目前所出现的问题 1、驱动包更新为 mysql-connector-java-8.0.12.jar 2、hibernate的配置文件hibernate.cfg.xml中使用 <property name"connection.driver_class">com.mysql.cj.jdbc.Driver</property>取代之前的 <property name"connection.d…

支持断线重连、永久watcher、递归操作 ZooKeeper 客户端

项目介绍 ZooKeeper本质上是一个分布式的小文件存储系统。原本是Apache Hadoop的一个组件&#xff0c;现在被拆分为一个Hadoop的独立子项目。 Zookeeper 作为一个分布式的服务框架&#xff0c;主要用来解决分布式集群中应用系统的一致性问题&#xff0c;它能提供基于类似于文…

mongdb总结

#清屏 cls --windows #操作数据库 show dbs --查看所有数据库 use dbName --使用已有的dbName数据库&#xff0c;或者创建新的数据库dbName&#xff0c;如果一个数据库没有表就不存在 db --显示数据库名称 #操作集合 show collections …

JavaScript操作BOM简单案例

需要两个页面index.html和Test.html&#xff0c;可以直接运行&#xff0c;每个功能都已经注释完整&#xff0c;index.html页面的代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head…

Java中“/”,“.”所代表的文件路径

转载自 Java中“/”&#xff0c;“.”所代表的文件路径 我们在开发的过程中&#xff0c;经常会去读、写文件。在读写文件的时候&#xff0c;就不得不写文件的路径&#xff0c;使用相对路径的方式有两种&#xff1a;”/”和 “.” 。在写文件的路径的时候&#xff0c;需要了解一…

Hibernate框架(1)

1.Hibernate框架简述 Hibernate的核心组件 在基于MVC设计模式的JAVA WEB应用中&#xff0c;Hibernate可以作为模型层/数据访问层。它通过配置文件(hibernate.properties或hibernate.cfg.xml)和映射文件(***.hbm.xml)把JAVA对象或PO(Persistent Object,持久化对象)映射到数据库中…

通过 Transifex 中文化开源软件

如果您对于汉化软件充满热情, 我软已经发布了以下的开源产品在 Transifex 平台&#xff0c;让社区的小伙伴们参与翻译以及审核: 如何参与? – Transifex 的新手 登录 Transifex 如果您第一次使用 Transifex, 您可以新建立一个账号或是通过您的 GitHub, Google 或 LinkedIn 账号…

JavaScript操作DOM元素

一、DOM&#xff1a; Document Object Model&#xff08;文档对象模型&#xff09; 二、DOM的分类&#xff1a; 1.DOM Core&#xff08;核心&#xff09; 2.HTML-DOM 3.CSS-DOM 三、节点属性&#xff1a; 1.lastElementChild:最后一个节点 2.firstElementChild:第一个节点 3.ne…

hibernate的lazy的使用

引用&#xff1a;https://blog.csdn.net/Vincent_yuan1991/article/details/53482487 一&#xff1a; lazy&#xff0c;延迟加载 Lazy的有效期&#xff1a;只有在session打开的时候才有效&#xff1b;session关闭后lazy就没效了。 lazy策略可以用在&#xff1a; 标签上&#x…

React中路由组件与一般组件

四、路由组件与一般组件 1.写法不同&#xff1a;一般组件&#xff1a;<Demo/>路由组件&#xff1a;<Route path"/demo" component{Demo}/>2.存放位置不同&#xff1a;一般组件&#xff1a;components路由组件&#xff1a;pages3.接收到的props不同&#…

第六期.Net开源社群联合分享--除了情结和价格,Azure最适合什么场景?等你来讲趟坑的实战经验!

嘿嘿&#xff0c;大家好啊&#xff01;好荣幸啊这一期&#xff0c;能够咱们.NET开源社区一块来做这次线上分享会。 我就是各位小伙伴可爱而且博学而且低调而且人见人爱花见花开而且谦虚但是经常口不择言的主持人老板娘Grace。 这次有新朋友&#xff0c;有老朋友&#xff0c;有…

jQuery选择器整理

第六章jQuery选择器一、jQuery选择器的分类&#xff1a; 1.基本选择器 2.层次选择器 3.属性选择器 4.基本过滤选择器 5.可见性过滤选择器 二、jQuery的基本选择器&#xff1a; ///基本选择器 //id选择器 //$("#div1").css(“background”,“red”); //class选择器 /…

遍历HashMap的四种方法

在Map集合中 values():方法是获取集合中的所有的值----没有键&#xff0c;没有对应关系&#xff0c; KeySet(): 将Map中所有的键存入到set集合中。因为set具备迭代器。所有可以迭代方式取出所有的键&#xff0c;再根据get方法。获取每一个键对应的值。 keySet():迭代后只能通…

支付系统的防重设计

转载自 支付系统的防重设计 导读 “目前在互联网应用的大部分支付场景中&#xff0c;对接支付宝、微信移动支付产品这样需要用户参与支付流程的支付方式已经变得非常普遍&#xff0c;类似的还有PC端银行网银支付&#xff1b;而通过绑定用户银行卡、对接银行卡快捷支付通道直接…

React中antd的按需引入+自定主题

antd的按需引入自定主题 1.安装依赖&#xff1a;yarn add react-app-rewired customize-cra babel-plugin-import less less-loader2.修改package.json...."scripts": {"start": "react-app-rewired start","build": "react-app-…