分享到

简介

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

尽管存在这些顾虑,但越来越多的趋势是在生产环境中完成部分测试。这种策略,简称为生产环境测试或 TIP,可以帮助团队更好地了解新代码将如何与实际系统和数据交互,并与之兼容。

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

什么是生产环境测试?

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

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

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

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

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

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

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

缺陷风险

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

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

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

对实时系统的影响

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

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

如何进行生产环境测试

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

实施功能标志系统

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

允许您的新代码从生产数据库读取数据是相当简单的。只要测试不会导致严重的读取争用,它就不会显着影响数据库的生产职责,并且对您的生产数据没有危险。

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

结论

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

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

关于作者
Justin Ellingwood

Justin Ellingwood

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