机房360首页
当前位置:首页 » 技术前沿 » 功能和集成测试(FIT)框架有什么样的设计和开发

功能和集成测试(FIT)框架有什么样的设计和开发

来源:机房360 作者:Harris编译 更新时间:2022/4/15 8:36:56

摘要:本文首先介绍高级的架构洞察力。然后引导完成框架的开发。还将介绍测试事务SDK所涉及的各种问题及其解决方案,并在整个框架的开发过程中使用相关示例。尽管并未提及该框架的所有技术细节,但提供了该框架的整体图景。

  本文描述了在分布式环境中Couchbase事务测试框架(即FIT框架)的设计和开发。
  
  本文首先介绍高级的架构洞察力。然后引导完成框架的开发。还将介绍测试事务SDK所涉及的各种问题及其解决方案,并在整个框架的开发过程中使用相关示例。尽管并未提及该框架的所有技术细节,但提供了该框架的整体图景。
  
  Couchbase目前在多个软件开发工具包(SDK)中提供事务:Java、Dotnet和CXX,并计划在不久的将来支持其他SDK。提供相同功能的测试SDK在测试自动化过程中会带来一些问题。测试自动化冗余是人们首先想到的问题。除了冗余之外,还必须确保所有SDK都具有类似的Couchbase事务。例如:所有SDK都完全相同地完成错误处理。这些只是其中几个问题。本文主要关注事务,将提供开发人员在测试多个SDK时会遇到的各种问题,以及Couchbase如何解决这些问题。
  
  Couchbase事务简介
  
  分布式事务(ACID)确保当需要修改多个文档时,只有成功修改所有文档才能证明其修改任何文档是正确的,要么所有修改都成功,要么都不修改。
  
  (1)分布式环境中的事务
  
  单节点集群:Couchbase事务在多节点和单节点集群上工作。但是,Couchbase应该支持集群配置。
  
  N1QL查询的事务支持:确保集群中至少有一个节点具有查询服务。
  
  (2)Couchbase事务SDK测试
  
  在框架的设计阶段,对测试计划及其自动化的深入分析带来了多重挑战。以下是一些主要挑战及其解决方案。接下来讨论这个问题及其解决方案,将看到框架开发的进展。
  
  问题1:冗余问题
  
  在Couchbase,目前支持3种不同SDK中的事务:Java、Dotnet和CXX。在不久的将来将支持更多的SDK,其中包括Golang。这显然为开发人员提出了冗余问题,即必须为每个SDK多次自动化相同的测试用例。
  
  解析:每个测试用例可以分为三个主要部分:
  
  •测试准备,例如:测试数据、测试基础设施等。
  
  •测试执行,例如:事务操作执行,即插入、替换等。
  
  •结果验证。
  
  仔细观察这三个部分,就会发现SDK测试只涉及测试执行阶段,而测试准备和结果验证实际上独立于SDK,因此使用哪个SDK并不重要。这导致设计了一个由驱动者和执行者两部分组成的框架。驱动者负责完整的测试准备和结果验证。驱动者驱动测试执行,但只是抽象的,也就是向执行者发出命令,执行者接受这些并执行实际的测试执行。
  
  FIT框架是在客户端-服务器模型中设计的,其中驱动者充当客户端,执行者充当服务器。
  
  •驱动者:包括所有测试准备和结果验证。所有测试都是经典的Junit测试,可以作为单个单独的测试或特定的测试套件或整个测试套件执行。所有的测试只写一次,而这些测试可以重复用于所有SDK。
  
  •执行者:这是一个为每个SDK编写一次的简单应用程序。在执行者内部,每个测试都以Java对象的形式进行建模,并发送到gRPC层。gRPC协议将这一Java对象转换为特定于语言的测试对象,并将其发送给执行者。执行者获取这一测试对象,读取指令,并执行所需的事务操作。在事务完成后,执行者检索结果并通过gRPC协议将其发送回驱动者。
  
  驱动者在接收到结果对象之后,将继续执行结果验证测试。
  
  •开发过程:既然对驱动者和执行程者如何在FIT框架内运行有了一个顶级概念,以下通过几个简单的示例测试来看看它的技术方面以及如何相互交互。
  
  示例1:使用单个操作测试事务:基本的“替换”操作
  
  驱动者代码:
  
  所有测试总是只编写一次,并且作为Junit测试。
  
  测试准备和结果验证独立于SDK,因此在Junit测试本身中完成。
  
  但是,测试执行部分是以抽象的方式完成的。在顶部,它看起来像是在驱动者本身中执行的。但是它在远程过程调用之后从事分布式计算。整个测试使用TransactionBuilder类转换为Java对象,在FIT框架中命名为“TransactionBuilder”对象,然后使用“sendToPerfomer”方法通过gRPC层发送到执行者。
  
  在尝试测试事务替换操作的这个示例中,创建了一个包含所有详细信息的Java对象:
  
  •事务应该在其上执行的文档ID。
  
  •更新值,即希望事务强加给文档的新值。
  
  •事务操作,在这种情况下是“替换”。
  
  在创建了这样一个java对象之后,sendToPerformer就会调用gRPC调用将它发送到服务器。
  
  因此,在第一步中,执行者读取测试对象并检查它需要执行的操作。在这个示例中,由于它是一个替换操作,op.hasReplace()将返回true,op.hasInsert()、op.hasRemove()等将返回false。
  
  在替换代码块中,执行者检索文档id、文档的位置和文档的更新值。一旦检索到所有相关信息,执行者就会执行事务,即ctx.replace()操作。
  
  一旦事务成功执行,将结果发送回驱动者,然后驱动者类似地从结果对象中检索相关信息,并执行结果验证。
  
  测试的功能示例:该框架的这一特性帮助测试事务SDK,不仅测试文档内容,还测试事务元数据,即在必要时提供预期元数据,并在必要时删除元数据。
  
  在对FIT框架有了一些技术见解之后,以下进一步了解一下细节:
  
  示例2:使用多个操作测试事务:
  
  驱动者代码:
  
  在这个测试中,事务使用docId1插入文档,并使用docId2替换文档。因此,必须将“插入”和“替换”添加到测试对象中,并将每个这些操作所需的所有信息发送给执行者。
  
  因为已经插入并替换了op.Insert,所以执行者将返回true,并检索所需信息并执行Insert,然后op.replace()将返回true,然后执行者执行替换操作,并将结果返回给驱动程序。
  
  功能测试示例:最初不支持在同一事务中对同一文档进行有效的多事务操作。在添加之后,可以使用框架的这种行为来测试该功能。此外,还测试了对不同文档的常规多次事务操作。事务无法替换/删除文件和到期等问题在这一支持下得到了很好的测试。
  
  在两个示例中都看到了事务有望成功的情况。但是,对于负面情况,预计事务会引发错误/异常。这些错误/异常是SDK特定的,因此它们需要由执行者处理。所以驱动程序需要告诉执行者什么错误/异常,而执行者需要做这个验证。
  
  问题2:错误验证
  
  •对于不同的原因,事务应该了解原因并找出相关的错误/异常。所以不仅要测试事务的功能,还要测试它们出现的错误代码和异常。
  
  •每个错误/异常的事务异常处理是不同的。例如:文档未找到异常的处理方式应与某些瞬态异常不同。
  
  •即使对于相同的异常,事务发生的阶段也会导致不同的处理方式。例如:插入/替换的写入冲突与忘记操作的处理方式不同。
  
  解决方案:驱动程序应将原因和异常的代码发送给执行者。执行者将读取故障原因的代码,并使用Hooks引发它们。
  
  Hooks是内部Couchbase实现,有助于测试失败场景。在下面的示例中,只是尝试在插入文档之前创建一个到期时间。
  
  一旦引发失败,执行者还将期望此事务应该出现的错误/异常。因此,执行者将检索异常并对其进行验证。如果未出现异常或不正确的期望,则执行者将无法通过测试,并将结果对象中的失败发送给驱者。驱动者读取这个结果对象,并将预期故障和实际故障作为输出。
  
  示例3:测试否定案例场景
  
  驱动者代码:
  
  所以在这个测试中,驱动者告诉执行者执行插入,然后期望事务在这个插入操作期间到期。发送代码“EXPECT_FAIL_EXPIRY”以将其传达给执行者。
  
  测试的功能示例:所有错误/异常处理和错误代码都经过测试。与SDK中的任何功能处理不一致或与SDK中的任何功能处理不相关。在这个框架的支持下,事务到期的特性得到了很好的测试。
  
  问题3:版本管理
  
  开发人员必须测试事务的不同库版本,并且以后的版本会具有以前版本中没有的新功能。因此,测试框架必须了解哪些功能不受支持,并避免运行这些测试。
  
  解决方案:使用了Junit5条件测试执行扩展。每个测试套件都用“@IgnoreWhen”条件注释。这里提到的所有条件都将被检索,并在重写的“ExecuteWhen”方法中使用。在驱动者开始执行任何测试之前,它会联系执行者并获得支持的所有功能。“ExecuteWhen”方法将使用“@IgnoreWhen”中提供的信息和执行者能力来决定是否需要执行或忽略测试套件。
  
  测试的功能示例:开发的SDK比其他SDK晚一些,一旦实现了它们的特性,就可以使用FIT的这个特性来打开这些测试。这有助于测试驱动的开发。
  
  问题4:多个执行者:并行事务
  
  事务可以并行执行。Couchbase事务确认了隔离模型。即当在同一组文档上执行两个或多个事务时,不应导致脏读和脏写。为了测试这一点,如果随机并行运行“n”个事务,万一导致文档损坏,就很难知道究竟是什么原因导致了损坏。每个事务可以有多个操作,每个操作都有多个阶段。如果需要解决问题,需要知道这些事务在什么操作和什么阶段出现冲突。
  
  解决方案:设计一个锁存机制,其中一个事务执行几个操作或一个操作中的几个阶段,并通知另一个事务开始。第一个事务现在等待第二个事务运行并达到所需的阶段。一旦第二个事务到达特定阶段,它就会通知第一个事务继续进行。即使对于并行事务,也行之有效。所以想出了一组可能导致写入冲突或脏读的冲突点,并使用锁存器来自动化这些测试用例。
  
  测试功能/发现错误的示例:使用此支持测试并发事务.
  
  问题5:多个执行者:不同SDK的并行事务
  
  由于支持多个SDK中的事务,因此在测试不同SDK中事务的并行执行时可以使用相同的逻辑。例如:Java事务与CXX事务。在上面的例子中可以采用同一个执行者,因为想为同一个SDK运行并行事务。在这种情况下,TXNA将连接到执行者A(假设执行者A正在使用Java事务),而TxnB将连接到执行者B(运行CXX事务)。
  
  测试的功能/发现的错误示例:使用这一支持测试了与不同SDK客户端的并发事务。还帮助确保事务元数据完好无损。
  
  结论
  
  FIT框架的这种架构设计不仅帮助解决了带来的问题,还进行了提高效率的测试自动化,帮助测试驱动开发(TDD)模式下的事务开发。
  
  高效的测试自动化:将框架拆分为单个驱动者和多个执行者帮助独立开发框架的各个部分。每个SDK的开发人员都提供了执行者,而开发人员可以专注于测试自动化(即驱动者)。开发人员还可以将单元测试添加到驱动者中,以便所有事务测试都由这个单一框架处理。
  
  测试驱动开发(TDD):开发了Java执行者并编写了所有需要的测试,以开发JavaSDK的最初几个版本的事务。一旦JavaSDK发布并开始开发其他事务SDK(即CXX和dotnet),开发团队必须在重用相同的驱动程序应用程序的同时开发执行程序应用程序。这有助于他们以TDD方式开发SDK。
  
  编辑:Harris
  

机房360微信公众号订阅
扫一扫,订阅更多数据中心资讯

本文地址:http://www.jifang360.com/news/2022415/n8501145129.html 网友评论: 阅读次数:
版权声明:凡本站原创文章,未经授权,禁止转载,否则追究法律责任。
转载声明:凡注明来源的文章其内容和图片均为网上转载,非商业用途,如有侵权请告知,会删除。
相关评论
正在加载评论列表...
评论表单加载中...
  • 我要分享
推荐图片