无需测试环境!如何利用测试脚手架隔离微服务,实现功能自动化

news2024/11/15 18:32:30

以下为作者观点:

想在不建立完整测试环境的情况下测试微服务?

想在将变更推送到主线分支之前完成测试?

这是我们在进行项目交付时经常遇到的难题。最近,当我们开始一个新的项目,为客户构建一个新的聚合平台时,我们希望将尽可能多的测试和自动化转移到流程的合并前执行。

我们知道,我们需要一种方法来对我们的服务执行深度功能测试,并使我们的团队能够独立运行。这就是促使我们开发用于微服务隔离和测试的测试脚手架(Test Scaffolding)的原因。

挑战

在部署到集成环境之前,我们需要独立于其他服务对微服务的变更进行测试。这样,当我们将变更部署到上层环境时,就可以专注于测试集成和事务流,而不是单个服务的功能行为。

虽然我们可以将测试中的服务指向其依赖的测试环境,但这可能会导致两个问题。

  • 首先,环境用户之间的数据混合会导致意想不到的行为。

  • 其次,由于服务之间的连锁调用,可能会出现延迟问题和测试缓慢。我们很快意识到,我们需要在合并前隔离服务的能力,以实现集中和完全隔离的功能测试自动化。

方法

我们决定通过引入一个名为测试脚手架Test Scaffolding的概念来隔离服务。

测试脚手架的工作是模拟微服务可能需要与之交互的所有外部服务。测试脚手架的作用与建筑脚手架的作用类似,随着微服务交互的增加,会将其添加到脚手架中。每个服务都有自己的脚手架,与服务预合并(the service pre-merge)一起构建和部署。

这样就为我们的微服务提供了它所期望的依赖关系,并通过测试对输入和输出进行细粒度控制。

这种方法对于独立构建服务并向我们的工程团队提供持续的早期反馈也至关重要。

微服务基础知识


我们将在下面的示例中使用 AWS 术语,但这些概念应适用于所有平台。

开始之前,我们必须对如何定义与测试脚手架交互的功能测试范围有一个共同的理解:

  • 测试仅限于特定微服务的边界。

  • 测试已部署服务的交互属于我们的行程测试(journey tests)。

  • 在项目中,我们将微服务的边界定义为服务CloudFormation Template(CFT)所定义的组件。

微服务中最常见的组件通常是API Gateway、Lambdas、Dynamo 和 SNS 或 SQS 的组合,我们可以用这样的图来表示:

图片

在这个例子中,假设我们需要测试微服务A,微服务A在给定的数据流中与微服务B和C通信。由于这些服务的目的非常集中,因此它们必须联系其他服务来验证外部信息。

图片

微服务A与微服务B 、C对话

我们不想让B和C的实例来测试A,所以我们需要隔离一些交互:

图片

挑战:将A与B和C隔离


这正是测试脚手架的作用。它取代了服务B和C的位置,在测试中提供了大量关于如何设置和管理输入和输出的控制。
 

图片


有几点需要注意:

  • 每个服务只有一个测试脚手架。我们可以根据需要在单个测试脚手架中添加多种不同类型的交互--即使它们代表不同服务的不同端点。

  • 微服务和测试脚手架都由各自的 CloudFormation 模板(CFT)定义,但存储在同一个项目 repo 中。

使用案例示例:

既然我们已经定义了微服务的边界,那就来讨论几个用例吧。

在第一个示例中,服务接受 API 请求,处理请求,然后通过 SNS 主题发送输出。我们在项目中使用这种模式将信息发送到不同的聚合器服务,这些聚合器服务会将数据映射成正确的格式,然后发布到多个第三方服务。

我们要确保输入值得到正确处理,并输出到 SNS 主题。与 SNS 交互非常棘手,因为它需要订阅才能捕获响应。这很难在自动测试中即时完成,因此我们添加了一个 Lambda 来处理对 SNS 主题的订阅,并添加了 DynamoDB 来保留响应,以便对测试脚手架进行验证。

图片

这样,测试就可以向服务发送请求,让服务处理请求,然后从脚手架 DynamoDB 中提取发送到 SNS 主题的结果,以确定结果是否符合我们的预期。

第二个示例与第一个示例类似。在这里,我们的微服务从 SNS 主题获取事件,并调用服务进行额外的状态验证,例如产品是否处于活动状态。然后,该状态将发布到映射的外部服务。

在这种情况下,我们的测试脚手架将包含 SNS 主题、API 网关、Lambda 和 Dynamo。测试会将我们希望服务从测试脚手架 API 调用中接收的数据填充到 Dynamo 中,并触发 SNS 主题流以启动测试。在处理过程中,微服务会将其状态调用发送到测试脚手架中的 API 网关,并获取测试在此暂存的响应。我们在微服务的 DynamoDB 中验证流程的最终输出。

图片

如示例所示,使用测试脚手架可以让我们高度灵活地匹配服务的交互要求,从而可以完全隔离地测试每个服务。

脚手架设置、部署和执行

那么,我们是如何配置这些服务从而确保它们在正确的区域内运行的呢?

为了取得成功,我们在云组建模板中进行了参数化。测试脚手架和被测微服务都有各自的 CFT 来管理必要的资源。在微服务 CFT 中,我们利用模板参数化和条件语句来控制测试脚手架的使用,具体取决于服务的部署方式。这些参数通过 CI/CD 管道传入。在我们的预合并部署中,这可以让微服务寻找测试脚手架,而在集成环境中,我们可以让该服务寻找适当的已部署服务。

下面是根据输入参数有条件使用测试脚手架的微服务 CFT 片段:


Conditions:

condIsProd: !Equals [ !Ref paramEnvironment, prod ]

condNotFeatureBranch: !Equals [!Ref paramFeatureBranch, ""]

condIsLocal: !Equals [ !Ref paramEnvironment, local ]

condIsLocalOrBranch: !Or [ !Not [ Condition: condNotFeatureBranch ], Condition: condIsLocal ]





Resources:



resLambdaConvertPicture:

Type: AWS::Serverless::Function

Properties:

Handler: ConvertPicture.handler

FunctionName: !Sub "${paramEnvironment}${paramFeatureBranch}_${paramServiceName}_ConvertPicture"

CodeUri: dist/ConvertPicture.js

Policies:

- SNSPublishMessagePolicy:

TopicName: !If

- condIsLocalOrBranch

- !Sub "${paramEnvironment}${paramFeatureBranch}_${paramServiceName}-ts_catalog_pictureUploaded"

- !Sub "${paramEnvironment}${paramFeatureBranch}_catalog_PictureUploaded"

- DynamoDBCrudPolicy:

TableName: !Ref resDynamoMenuJobsTable

测试脚手架作为分支部署的一部分与微服务同时部署。下图显示了脚手架代码必须遵守与其他服务相同的部署标准。部署完成后,我们将运行功能测试。

图片

带有测试脚手架的分支部署CI/CD管道图。

只有当使用脚手架的隔离服务测试通过后,才有可能并入主线分支。测试脚手架不会部署到我们的集成环境中。一旦主线中出现变更,我们就会使用计划作业来清理任何可能尚未手动拆除的隔离环境(服务和脚手架)。这一点很重要,因为给定账户的可用资源数量是有上限的。

测试,更上一层楼

测试脚手架允许我们的团队在合并到主线分支并部署到集成环境之前,使用与服务开发完全相同的技术(CFT 和本地 AWS 资源)独立开发和测试微服务功能。通过脚手架控制输入和输出,我们可以围绕关键流程建立更深入的测试集,并有效地确保高质量。

由于测试脚手架允许我们创建的不仅仅是基本的创建、读取更新和删除测试,我们还能构建与业务用例相关联的深度功能流。这些深入的功能测试让我们对微服务在合并到主线并部署到环境中之前的变化充满信心。此外,将大部分自动化保持在这一级别(以及单元测试)可最大限度地减少行程测试(journey test)(即:"端到端测试")的使用,并支持测试金字塔所有级别的健康自动化套件。

一些亮点:

  • 每次推送到版本库时都会执行测试。

  • 测试速度快!针对我们的一项主要服务进行的几百个测试中,运行时间最长的一组测试不到10分钟。

  • 测试对即将进行的合并进行把关。如果测试不通过,你的提交就无法合并,也不会影响其他团队在其他服务上的工作。

  • 测试定义并控制自己的所有数据,使其具有完全的确定性和密封性。

经验教训

在我们学习实施和利用测试脚手架的最佳方法时,需要不断地尝试和犯错。我们既要确定如何将其纳入项目,又要确定将其作为管道的一部分进行构建和部署的最佳方式。以下是一些关键经验:

KISS-("Keep It Simple, Stupid")我们倾向于将测试脚手架中的行为复杂化,从而不需要重复依赖逻辑来生成适当的响应。

清理- 当变更提交到主线时,服务和测试脚手架的测试版本就会被遗留下来。因此,我们建立了清理工作,以便从AWS开发账户中删除不再处于活动开发阶段或已数天未更新的工件。事实上,一切都由云形成堆栈定义,这使得根据需要重新部署变更变得非常容易。

契约演进(Contract evolution) - 测试脚手架中使用的请求和响应与实际服务契约保持一致至关重要。否则,就无法测试应该测试的内容。团队间的沟通和合同测试仍然至关重要。

与任何新流程一样,测试脚手架的开发和部署也需要时间和精力,但它最终成为了我们整体微服务开发方法中的一个强大工具和重要资产。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

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

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

相关文章

【springboot】springboot接口参数全局解密,解决request内容修改后如何重新设置回去的问题

文章目录 核心思路spring&servelt基础核心接口类body解密核心原理讲解get解密核心原理讲解 核心思路 拦截每次请求 所以要么在拦截器 要么在过滤器中做 (正常来说 其实只能在过滤器做)修改request中的参数把修改后的参数设置回去(难点) spring&servelt基础…

RegFormer:用于大规模点云配准的高效投影感知Transformer网络

目录 一、导言 二、相关工作 1、点云配准工作 2、大规模点云配准 3、Transformer引入配准工作 三、RegFormer 1、柱面投影 2、特征提取Transformer 3、双射关联Transformer(BAT) 4、刚性变换估计 5、损失函数 四、实验 一、导言 该论文来自于ICCV2023(…

如何搞定聊天记录找回?三款数据恢复工具分享

聊天记录丢了怎么办?别急,我这就带大家看看市面上比较火的三款数据恢复软件在恢复聊天记录方面的表现如何。首先,我们得知道,聊天记录这东西,一旦误删,那可是心急如焚啊。所以,选择一款靠谱的数…

场外个股期权可以分批建仓吗?

场外个股期权的优势是可以进行风险的精细化管理,但由于期权价格变化的非线性特性,盈利与标的行情走势的相关性不断变化,场外个股期权最便宜的可以用2-5万买到100万市值的股票持仓一个月,下面是整理得出的场外个股期权可以分批建仓…

SwiftUI 6.0(iOS 18)监听滚动视图视口中子视图可见性的极简方法

概览 在 SwiftUI 的应用开发中,我们有时需要监听滚动视图中子视图当前的显示状态:它们现在是被滚动到可见视口(Viewport)?或仍然是隐藏在“未知的黑暗”中呢? 在 SwiftUI 早期版本中为了得偿所愿,我们需要借助一些“取巧”的手段。不过,从 SwiftUI 6.0(iOS 18)开始情…

echarts柱状图使用自定义图片填充柱体

这是我的柱状图图片纹理的实现过程的流水账式记录 方法一: 在option.series里面,给每一项配置上图片路径 let Image2 new Image() Image2.src src/assets/image/BarChart-line.pngcolor: {image: Image,repeat: repeat } 出来的效果比较适合整体纹样…

[Linux]如何在Ubuntu中安装Docker,并且学习基本操作?

一、我们为什么需要Docker? 相信大家都遇到过部署一个应用时缺少依赖的情况,往往我们需要手动解决依赖问题,在解决了依赖问题以后,好不容易安装了这个应用,但是我们更换了计算机以后又需要重复上面步骤将这个软件再安装…

Unity(2022.3.38LTS) - Project Settings详细介绍不看你就亏大了(一)

目录 一. 简介 二. 详细介绍 1. Adaptive Performance(自适应性能) 2.音频 3. 编辑器 4. 图形 5. 输入管理器 6.包管理器 7.物理 8.2D物理 9.玩家 10.预设管理器 一. 简介 在 Unity 中,Project Settings(项目设置)页面是一个非常…

企业组网中MPLS和SD-WAN方案各有什么特点?

MPLS(多协议标签交换)和SD-WAN(软件定义广域网)是企业组网的两大关键技术方案,各自具备独特的特点和优势。 MPLS作为一种传统的专线技术,通过给数据包附加标签,实现了网络流量的高效转发。这种方…

教你如何安装并使用小熊猫c++

目录 前言 一、获取安装包 二、安装 1.打开安装包 2.选择语言 3.接受协议 4.安装场景 5.选择组件 6.选择位置 7.完成安装 三、如何使用 1.打开软件并选择主题 2.创建项目 3.新建空项目 4.创建源文件 5.测试C语言代码 6.编译 7.运行 总结 前言 已有的C/…

地震采集的观测系统

这张图表明,为什么在速度分析论文中,与CMP有关的数据都有CDP序号的影子——因为CDP序号是对一条测线上布置的观测系统对地下反射点的信号记录。换句话说,不同的CDP序号(类似测井位置)意味着不同的CMP道集。 几种论文中…

【Python快速入门和实践013】Python常用脚本-目标检测之按照类别数量划分数据集

一、功能介绍 这段代码实现了从给定的图像和标签文件夹中分割数据集为训练集、验证集和测试集的功能。以下是代码功能的总结: 创建目标文件夹结构: 在指定的根目录(dataset_root)下创建images和labels两个文件夹。在这两个文件夹下…

scoket通信 -- 网络字节序

include <arpa/inet.h> 考虑到不同语言不同库函数的参数可能不同&#xff0c;我这里以c语言的arpa/inet.h库中的函数为例. 网络字节序是什么 网络字节序&#xff08;Network Byte Order&#xff09;是指在网络通信中用于数据交换时所采用的字节序&#xff0c;它是大端…

log4j日志配置%X{TransId}

log4j日志配置文件中的%X{TransId}是怎么动态获取值的 在Log4j中&#xff0c;%X{TransId} 是用来从MDC&#xff08;Mapped Diagnostic Context&#xff09;中获取值的占位符。MDC 是 Log4j 提供的一种机制&#xff0c;用于在同一个线程的不同日志记录中传递上下文信息。通过 M…

centos ssh免密登录配置

ssh免密登录 centos 系统中&#xff0c;配置免密需要确保ssh配置文件免密登录权限打开了 sudo vim /etc/ssh/sshd_config 查看PubkeyAuthentication值为yes 修改之后&#xff0c;重启sshd sudo systemctl restart sshd免密配置 &#xff08;1&#xff09;生成秘钥文件 ssh-…

Linux 下 RocketMQ 安装、配置与运维(详细讲解)

一 RocketMQ 下载安装 1 下载 RocketMQ&#xff1a; 下载当前最新版本RocketMQ 官网下载&#xff1a; https://dist.apache.org/repos/dist/release/rocketmq/5.3.0/rocketmq-all-5.3.0-bin-release.zip wget https://dist.apache.org/repos/dist/release/rocket…

安装搭建MongoDB及配置副本集

目录 一、什么是MongoDB的副本集 简介 &#xff08;1&#xff09;冗余和数据可用性 &#xff08;2&#xff09;MongoDB中的复制 &#xff08;3&#xff09;主从复制和副本集区别 二、副本集的架构 三、副本集的成员 四、部署副本集 1、节点划分 2、安装MongoDB 2.1、…

数据结构与算法——平衡二叉树

1、基本介绍 1&#xff09;平衡二叉树又叫平衡二叉搜索树(Self-balanceing binary search tree)&#xff0c;又被称为AVL树&#xff0c;可以保证查询效率较高。 2&#xff09;具有以下特点&#xff1a;它是一颗空树或它的左右两颗子树的高度差绝对值不超过1&#xff0c;并且左…

网络热门编程项目导学:尚医通

本文作者&#xff1a;程序员鱼皮 免费编程学习 - 编程导航网&#xff1a;https://www.code-nav.cn 现在网上有很多播放量巨高的免费编程项目教程&#xff0c;很多学编程的同学可能都看过&#xff0c;就导致大家可能写在简历上的内容都差不多。 于是就有了下面这张图&#xff1…

python之matplotlib (3 坐标轴设置)

写在前面 在说明坐标轴设置之前&#xff0c;我有必要和大家说清楚图像设置的一些方法&#xff0c;避免陷入困扰模糊的地步。前面我们说过&#xff0c;画图的三种方法&#xff08;python之matplotlib &#xff08;1 介绍及基本用法&#xff09;-CSDN博客&#xff09;。而设置也…