分享至

简介

软件开发中的测试通常被限制在与生产部署分离的开发和暂存环境中。这种隔离的原因是,一方面是为了最小化测试在生产流量中运行时的性能影响,另一方面是为了降低破坏性更改影响生产环境的可能性。

尽管存在这些顾虑,但越来越多的人开始在生产环境中进行部分测试。这种策略被称为生产环境测试或 TIP,可以帮助团队更好地了解新代码将如何与需要兼容的实际系统和数据交互。

在本指南中,我们将探讨在生产环境中测试软件更改的想法。我们将涵盖一些历史上对生产测试的抵制原因,以及使采用生产测试更具吸引力的变化,并讨论其对开发速度和错误减少的一些益处。

什么是生产环境测试?

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

乍一看,这个想法似乎违反直觉,甚至很危险。或许不出所料,它并非没有风险。然而,许多风险可以通过引入部署和测试策略来消除,这些策略不仅可以更彻底地测试您的软件,还可以让您构建更具弹性的生产环境。

生产环境测试之所以有价值,是因为它消除了由于生产环境和测试环境之间存在环境差异而导致的一类问题。与其在专用环境中进行测试,然后将通过测试的代码部署到生产环境中,希望其行为保持一致,不如在代码需要运行的地方进行测试。

采用生产环境测试理念的人员的重点可以总结如下

  • 尽快将代码部署到生产环境:这允许您的团队在代码需要运行的环境中尽早测试代码
  • 将代码部署与代码发布分离:将部署过程与发布更改的操作分离,可以为您在测试和激活新功能方面提供更多灵活性
  • 使用真实数据进行测试:数据库模拟或存根以及填充了虚拟记录的数据库无法准确地复制代码需要处理的数据
  • 最小化更改的影响范围:如果您可以在测试和发布期间限制和调整范围,则可以更安全有效地测试更改

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

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

缺陷风险

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

这种观点有其优点,但在实践中情况往往并非如此明确。组织在暂存环境中运行的测试通常不能很好地近似代码在生产环境中的处理方式。复制环境(包括基础设施和工作负载)并非易事,并且通常与实际生产系统脱节。

最终的结果是,您在暂存环境中测试的内容可能实际上并不适用于代码在发布后的执行方式。此外,无论成功与否,都需要投入大量的人力、时间和基础设施进行尝试。

对生产环境的影响

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

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

如何在生产环境中测试

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

实施功能标记系统

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

功能标记是生产测试中的宝贵工具,因为它们允许您安全地部署代码而不会影响生产系统的当前逻辑。可以停用新代码路径以启动,然后在准备好测试新代码时在以后的时间激活。功能标记概念的许多实现都包含比“启用”或“禁用”更细粒度的控制,可以选择为一定比例的流量启用它,对不同的逻辑进行 A/B 测试,或者只在特定情况下选择路径。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

更好但更难实现的选择是使用生产数据库进行测试。这可能难以实现,尤其是在您的数据库模式和工具从一开始就没有为此可能性进行配置的情况下,但这提供了了解代码在发布时如何执行的最佳机会。

允许您的新代码从生产数据库读取数据相当简单。只要测试不会导致大量的读取争用,它就不应该显着影响数据库的生产职责,并且不会对您的生产数据构成威胁。

但是,测试代码如何执行写操作要棘手一些。测试最直接的方法是在生产数据库中创建专用测试用户,以便您的新代码可以在不接触实际用户数据的情况下对数据进行操作。这仍然是一个相当可怕的建议,因为测试操作将在来自您的活动代码的真实数据旁边执行。

结论

在生产环境中进行测试可能难以实施,并且可能需要对现有项目进行许多更改。然而,采用一个系统,让你可以在重要的环境中测试代码的真实行为,其带来的好处难以言喻。测试旨在识别错误并增强对软件的信心,这两个目标在非代表性环境中很难完全实现。

通过了解这种方法所涉及的挑战,你可以评估它是否适合你组织的工作方式。生产环境测试是一种权衡,你的成功可能很大程度上取决于你愿意和能够投入多少精力。虽然它并不一定容易调整,但其优势可以让你在长期内受益。

关于作者
Justin Ellingwood

Justin Ellingwood

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