分享到

简介

传统上,软件开发中的测试被降级到与生产环境部署分离的开发和暂存环境。这种隔离背后的原因是,既要最大限度地减少与生产流量一起运行测试对性能的影响,又要降低破坏性更改影响生产环境的风险。

尽管存在这些担忧,但完成在生产环境内部进行部分测试的趋势日益增长。这种策略简称为生产环境测试或 TIP,可以帮助团队更好地理解新代码将如何与实际系统和需要兼容的数据进行交互。

在本指南中,我们将探讨在生产环境中测试软件变更的想法。我们将涵盖历史上对生产环境测试犹豫不决的一些原因、使采用更具吸引力的变化,并讨论它可能对开发速度和错误减少产生的一些好处。

什么是生产环境测试?

生产环境测试是一种理念,鼓励开发人员将部分或全部软件测试推迟到代码部署到生产环境之后。但是,为什么团队想要转向生产环境测试呢?

乍一看,这个想法可能看起来违反直觉,甚至很危险。也许不足为奇的是,它并非没有风险。但是,通过引入一种部署和测试策略,不仅可以更彻底地测试您的软件,还可以使您构建更具弹性的生产环境,从而消除许多风险。

生产环境测试很有价值,因为它消除了由于生产环境和测试环境之间的环境漂移而导致的一类问题。您无需在专用环境中进行测试,然后将通过测试的代码部署到生产环境,并希望其行为保持一致,而是直接在代码需要运行的环境中进行测试。

对于那些采用生产环境测试理念的人来说,重点可以总结如下:

  • 尽快将代码部署到生产环境: 这允许您的团队在代码必须运行的环境中尽早测试代码
  • 将部署代码与发布代码解耦: 将部署过程与发布更改的行为分开,使您在测试和激活新功能时具有更大的灵活性
  • 使用真实数据进行测试: 数据库模拟或存根以及填充虚拟记录的数据库无法准确复制您的代码必须适应的数据
  • 尽量减少更改的影响范围: 如果您可以在测试和发布期间限制和调整范围,则可以更安全有效地测试更改

生产环境测试有哪些风险?

许多人怀疑生产环境测试的好处是否能超过成本。在我们继续之前,让我们谈谈这种策略的一些风险以及如何减轻这些风险。

缺陷风险

在生产环境中测试代码的主要担忧是可能引入软件缺陷,这些缺陷可能会影响您的用户和服务。传统软件测试管道背后的想法是在将代码提升到生产职责之前,彻底审查代码并检查已知的弱点。

这种观点有其优点,但在实践中情况往往没有那么清晰。组织在暂存环境中运行的测试通常不能很好地近似代码在生产环境中将要处理的情况。复制环境,包括基础设施和工作负载,并非易事,并且常常与实际生产系统不同步。

这样做的结果是,您在暂存环境中测试的内容可能实际上不适用于您的代码在发布后将如何执行。此外,无论是否成功,尝试都需要大量的努力、时间和基础设施。

对生产系统的影响

一个密切相关的担忧是,新的更改和测试过程本身可能对生产环境产生影响。系统稳定性是大多数组织的首要任务,因为它会影响服务的可用性和可访问性,并损害用户信任。

虽然部署到生产环境的任何代码确实有可能影响运营,但有很多方法可以最大限度地减少潜在影响。实施控制以限制新代码接收的流量、设置活动备用基础设施以及实施基于监控的扩展是使此过程更安全的一些方法。关于这些类型的缓解措施的好处是,这些投资直接提高了您的生产系统对各种系统故障的弹性。

如何进行生产环境测试

生产环境测试实际上是如何工作的?在本节中,我们将讨论组织为在生产环境中可靠地测试代码而实施的一些最常见的技术和策略。虽然没有必要采用所有这些想法,但其中许多方法是相互补充的,并且可以集成为一个更全面的系统的一部分。

实施功能标志系统

功能标志是一种编程和发布技术,它使功能易于在外部激活或停用。基本思想是将新功能包装在条件逻辑中,该逻辑在运行之前检查配置变量的值。“标志”或“切换”变量通常配置在 Redis 等外部存储中,组织可以根据需要轻松更改该值。

功能标志是生产环境测试中的一个有价值的工具,因为它们允许您安全地部署代码,而不会影响生产系统的当前逻辑。新的代码路径可以先停用,然后在准备好测试新代码时稍后激活。功能标志概念的许多实现包括比“启用”或“禁用”更精细的控件,并可以选择为一定比例的流量启用它、A/B 测试不同的逻辑,或者仅在特定情况下选择路径。

通过使用功能标志,您可以将代码以停用状态部署到生产环境。您可以使用测试套件测试新的代码路径,而生产流量继续使用旧的逻辑。然后,您可以作为金丝雀发布逐步增加新代码路径接收的生产流量,同时监控影响,从而缓慢发布代码。

使用 CI/CD 在生产基础设施上部署和测试

关于生产环境测试的一个误解是,假设测试必须在生产环境中完成。虽然支持者认识到在代码最终运行的环境中进行测试的价值,但并非所有测试都需要这种程度的保真度,并且许多快速、集中的测试可以自动化并作为部署代码的准备工作的一部分运行。

实现此目的最简单有效的方法是通过经过良好调整的 CI/CD 管道。CI/CD,代表持续集成和持续交付或部署,是一个在向存储库添加新代码时自动测试新代码的系统。一旦测试套件成功通过,管道(持续交付)允许开发人员通过单击按钮来部署更改,而持续部署会自动部署所有成功测试的代码。

CI/CD 在生产环境测试的背景之外有很多好处。对于我们描述的系统,管道充当部署过程的自动化部分,目标是在生产环境中部署和测试。虽然像单元测试这样的简单测试可以单独完成,但像集成测试这样更复杂的阶段理想情况下应该通过将代码部署到生产基础设施并在那里进行测试来完成。这允许您的代码在最终运行的基础设施上针对它将与之交互的实际服务进行测试,并具有相同的运行上下文。

CI/CD 管道有助于建立对新更改的信心,并减轻对如此快速地将代码部署到生产环境的焦虑。结合功能标志,开发团队可以相信代码的某些方面已经过审查,然后可以控制如何进行更重的测试。

配置您的服务以允许暗启动

暗启动是一种部署软件更改并使用真实流量对其进行测试的方式,而不会产生面向用户的后果。其思想是镜像生产流量并将重复请求发送到您新部署的代码,以便您可以确保它既能正确执行又能处理实际的生产负载。

暗启动可能非常复杂,因为它要求您在应用程序的多个实例上重放现有流量,而不会导致影响测试合法性的速度减慢。实时复制请求的替代方法是从事件日志或其他来源回放以前的请求。此策略要求您捕获来自初始请求的所有相关上下文。

暗启动的好处是,它允许您查看您的代码如何像已经发布给用户一样运行。通过新代码运行流量的结果永远不会显示给用户,但它们可以提供有关您的代码行为方式以及它需要考虑哪些类型条件的见解。一旦您测试了暗启动版本的应用程序,您就可以相当有信心地了解它在生产环境中的性能,因为它已经面临了这些压力。

实施强大的监控和指标收集

除了在部署和发布期间执行的核心测试之外,重要的是要建立系统,使您能够在代码投入生产后继续监控其行为。可以实施各种相关技术来帮助您深入了解服务的长期运行状况,从而使您在新代码导致行为转变时更快地发现异常。

监控和指标跟踪是您可以用来了解服务在不同条件和随时间推移的表现的基本工具。新的更改可能会产生在短时间内难以发现的副作用,但随着时间的推移可能会变得明显。监控和指标可以帮助将这些行为变化与特定版本关联起来。

生产环境测试如何影响数据库?

生产环境测试最复杂的方面之一是找出一种有效的方法来执行与数据库交互的测试。虽然可以让您的新代码从不同的数据源读取和写入,但这再次引入了针对复制不良的环境进行测试的可能性。

更好但更难实现的选择是使用您的生产数据库进行测试。这可能很难实现,特别是如果您的数据库模式和工具从一开始就没有为此可能性配置,但它为理解您的代码在发布后将如何运行提供了最佳机会。

允许您的新代码从生产数据库读取数据非常简单。只要测试不会导致大量读取争用,它就不会显着影响数据库的生产职责,并且不会对您的生产数据造成危险。

然而,测试您的代码如何执行写入操作有点棘手。最直接的测试方法是在生产数据库中创建专用测试用户,以便您的新代码可以在数据上运行,而无需触及真实用户数据。这仍然可能是一个相当可怕的想法,因为测试操作将与来自您的活动代码的真实数据一起执行。

结论

生产环境测试可能难以实施,并且可能需要对现有项目进行许多更改。但是,采用一个可以在关键环境中测试代码真实行为的系统的好处是难以过分强调的。测试旨在识别错误并建立对软件的信心,这两个目标在非代表性环境中很难完全实现。

通过了解这种方法所涉及的挑战,您可以评估它与您组织的工作方式的契合程度。生产环境测试是一项权衡的练习,您的成功可能很大程度上取决于您愿意并且能够为此过程投入多少精力。虽然这不一定是容易的调整,但从长远来看,它的优势可以很好地为您服务。

关于作者
Justin Ellingwood

Justin Ellingwood

自 2013 年以来,Justin 一直在撰写关于数据库、Linux、基础设施和开发者工具的文章。他目前与妻子和两只兔子住在柏林。他通常不必以第三人称写作,这对所有相关方来说都是一种解脱。