左移测试是一种软件测试方法,其中将测试移至开发过程的早期阶段,更接近开发阶段。左移测试的目标是在开发周期中尽早发现并修复缺陷,从长远来看可以节省时间和资源。
在软件开发中更早地集成测试,可以更早地发现错误,加速反馈循环,并加快部署到生产环境的速度。
发布代码的最佳途径是什么?一个没有尖峰、没有灭火、没有拼命急于添加快速功能以满足企业客户要求的流程?当一切正常时,该过程如下所示:
十年前,项目经理嘲笑软件开发生命周期(SDLC)的瀑布式实现,其中阶段是严格定义的,规划阶段的工作从不与开发重叠,测试只有在开发结束后才开始。这种固定的过程意味着发布频率不高,并且需要很长时间才能获得用户反馈。瀑布特别不适合通过互联网交付的软件,在互联网上,敏捷方法可以每天发布软件,并在几周内反映用户的反馈。
虽然敏捷方法允许这些阶段重叠并强调交付速度,但这些阶段仍然是基于瀑布的,传统的开发、构建和测试方法不太适合现代基于微服务的环境。
当今测试的两个主要问题
尽管越来越多的工作负载正在迁移到微服务,但测试仍无法跟上现代开发需求。这里有两个原因。
QA应该找到回归,而不是回归到瀑布时代
虽然敏捷方法与在线软件交付的兴起密切相关,但使瀑布流过时的另一个组成部分是质量保证 (QA) 的自动化和民主化。随着自动化测试和 QA 与开发团队的集成程度越来越高,测试等待开发完成是不寻常的。现代流程定义了许多精细的测试等级,从单元测试到端到端测试,并在开发人员编写代码和连接服务时不断提供反馈。
微服务在某种程度上打破了这种范式,重新打开了通往瀑布世界的大门。从广义上讲,问题是相互依存。微服务非常依赖其他服务,因此在部署服务并与我们的其他组件和第三方 API 交互之前,很难获得准确的测试图。通常,QA 或运营团队是第一个发现微服务代码严重问题的人。
这种破碎范式的结果是,反馈在周期的后期出现,需要将发布带回开发的最初阶段。虽然这有时会发生在代码投入生产之后,但很多时候,测试的初始部署无法捕获后期阶段出现的问题,或者最终的金丝雀测试发现了应该在流程中更早出现的集成问题。真正的过程更像是这样的:
针对这些问题提供的最常见解决方案是构建单元测试、存根和模拟来模拟所有其他组件,但这种策略很少完全成功。一个可以模拟复杂集群的测试套件要么要求QA对堆栈中的每个服务都非常复杂,要么每个团队都愿意投入大量时间来维护其服务的测试并准确模拟其他服务。
测试对开发人员来说太慢了
当尝试模拟整个集群进行测试时,结果慢得令人无法接受。由于您必须在测试环境中运行整个测试套件,因此可能需要 20 分钟到几个小时才能运行所有测试并获得结果。即使是 10 或 20 分钟也足够长,开发人员不会坐下来等待所有测试在一天中运行几次。人们普遍认为,开发人员不会经常运行集成测试,更新后的服务会与集群的其余部分一起工作;相反,他们会等待在部署生命周期的后期运行它。
由于许多错误是在部署周期的后期发现的,因此还有另一个流程问题让人想起瀑布时代:当另一个团队的工程师发现错误时,诊断、报告和修复问题的过程变得繁琐。运营和 QA 工程师的任务是为每个集成问题提交错误报告,并要求开发人员在带外修复问题。
左移以修复测试和开发
若要修复开发和测试代码的过程,请左移:在周期的早期测试代码,并直接向开发人员提供反馈。左移是一种文化和实践的转变,但也包括对共享测试环境设置方式的技术更改。
更频繁地进行较小的更改
在理想的微服务 SDLC 中,重点是尽早且经常地集成测试,从开发阶段开始。这种方法强调了小的增量代码更改的重要性。通过将更改限制在范围内,开发人员可以更轻松地理解和测试其修改的影响。这种粒度不仅加快了验证过程,而且使测试更加精确。
在此模型中,开发人员拥有其代码的开发和测试的所有权。这种所有权明确了责任,从一开始就将质量放在首位。该方法可以在工程团队之间有效扩展,因为每个团队或开发人员都可以独立处理各自的服务或功能,从而减少依赖性。虽然这是一个很好的建议,但在当前的开发环境中实施起来可能很困难:如果将代码发布到共享测试集群的过程花费了太多时间,那么测试小的增量更改似乎不可行。最好实现一个共享的测试环境,开发人员可以在其中测试一些小的更改。
获得更快的反馈
该模型中的反馈循环速度很快。由于开发人员边做边测试,因此许多潜在问题会立即得到解决,通常是在它们被识别为传统意义上的错误之前。作为用户查找 bug 和作为开发人员查找 bug 之间的区别是巨大的:当运营或站点可靠性工程师 (SRE) 发现问题时,他们需要找到发布代码的工程师,描述他们看到的问题,并提供一些步骤来复制问题。相反,如果原始开发人员发现了问题,他们可以通过查看输出、找到原因并开始修复来减少所有这些步骤。这种主动的质量方法减少了在开发周期后期需要归档和解决的错误数量。
从文化上讲,这种 SDLC 模型培养了一种 CI/CD 文化,在这种文化中,代码更改可以快速可靠地集成、测试和交付。这不仅加快了开发过程,还提高了软件的整体质量。尽管 CI 意味着“持续集成”,但在微服务的上下文中,CI 工具以最佳方式提供持续测试,让开发人员尽早了解他们在尝试部署微服务代码时将面临的实际问题。
测试空间集成
集成用于预览代码更改的系统是一个关键组件,因为它允许即时反馈更改在实时环境中的行为方式。此类预览对于开发人员以及其他利益相关者(如项目经理和 QA 团队)来说非常宝贵。技术挑战是巨大的,而且没有“插入式”解决方案来创建一个非常准确的生产副本,每个开发人员都可以测试频繁的更改。
简而言之,任何此类系统的基本要求是:
· 生产环境的真实副本,包含所有必需的依赖项和由其他团队维护的许多微服务。
· 将新的小型代码更改部署到此共享环境的简单方法。
· 一种防止冲突的方法,以便部署到服务的实验性代码不会中断其他开发人员的群集性能。
通常,承诺仅在需要测试时才建立整个集群副本的解决方案并不令人满意。相反,开发人员需要进行小的增量更改,有时一天部署不止一次。一旦事情变得非常复杂,建立整个集群所需的时间将抑制左移的目标。
请求左移隔离
面向开发人员的快速准确的测试环境必须是 Kubernetes 空间的原生环境,以便动态地允许在使用运行生产环境的系统的共享集群中进行更新和测试。许多大型企业团队已经实现了一种称为请求隔离的模型,该模型允许测试服务作为集群的一部分运行,而不会中断其他服务。包括 Uber 和 netflix 在内的团队可以推出服务的测试版本,甚至可以推送到生产环境,该版本只能处理测试请求,但仍然可以向它所依赖的所有其他服务发出请求。
netflix 允许开发团队在其集群上使用请求隔离技术。通过利用服务网格,工程团队可以仅将测试请求定向到其服务的更新版本。使用测试版本更新服务时,服务的基本版本仍可供其他团队使用,因此他们可以使用相同的测试群集。
结果使团队能够进行小的增量更改,并针对实际集群进行测试。开发人员自己发现问题,大大缩短了反馈时间并加快了开发速度。
作者:架构摆渡