微服务中的端到端测试(三)

2024-11-03   出处: substack.com  作/译者:Rafael dos Santos Miguel Filho/溜的一比

难以确定失败原因:异步环境中的调试挑战

在异步通信存在的地方,调试失败可能变得极其复杂和令人沮丧。想象一个假设的场景,一个大型应用程序由几十个微服务组成,其中许多通过消息队列(如RabbitMQ或Kafka)进行通信。现在,想象你正在运行一个端到端测试套件,以验证关键业务流程,如处理金融交易。

支付流程

让我们假设一个支付流程。假设服务A接收到一个支付请求,处理初始数据,然后向队列发送一条消息,以便服务B执行反欺诈验证。服务B在完成验证后,向服务C发送另一条消息,服务C则扣减用户的账户并完成交易。

现在,在端到端测试执行期间,出现了失败。系统未能完成支付,测试失败了。但为什么会这样呢?这是软件工程师需要回答的一些问题:

  • 服务A未能将消息发送到队列?
  • 或者服务B当时不可用,导致消息丢失或被忽略?
  • 或者服务C接收了消息,但无法访问数据库以完成扣款?

每个步骤都是异步的,可能独立失败,增加了确定根本原因的难度。

消息进入DLQ中的头痛问题

现在,考虑一个特定场景:服务A将消息发送到队列,但由于某种原因——例如配置错误、临时网络故障或服务B不可用——该消息从未到达目的地。因此,服务B没有处理该事务,服务C也没有收到指令扣减客户的账户。当测试失败时,你看到的只是交易未完成,消息进入了代理的DLQ(死信队列)。但根本原因,即丢失的消息,可能隐藏在表面之下的几层。

此类问题不仅难以识别,还难以修复。你可能需要几分钟甚至几小时来检查日志、重新测试和调整配置,才发现问题是一小段服务之间的通信故障。如果该故障是间歇性的,它可能在某些测试中未被发现,而在其他测试中则被捕捉到,使调试变得更加复杂。

模拟与现实

面对这一挑战,一些工程师可能选择模拟某些服务或队列,以使测试更加可预测且不易因临时不可用或配置错误而失败。但这里有一个重要的问题:通过模拟这些交互,我们真的在进行端到端测试吗?

在单元测试或集成测试中,模拟可能是合适的,在这些测试中你希望隔离组件并确保它们独立工作正确。然而,在端到端测试中,目标是验证整个业务流程,包括服务之间的通信,在尽可能接近现实的环境中是否按预期工作。如果你开始用模拟替换系统的关键部分,那么你就妥协了这些测试的完整性。

所以要保持警惕,始终质疑并评估使用模拟的必要性。

异步测试的时间与复杂性

考虑到端到端测试在异步环境中运行的时间可能显著延长,对开发周期的影响是显而易见的。每次测试失败,工程师需要花费时间进行调查,从而减缓了新功能的交付速度,并可能增加妥协质量的压力。此外,依赖异步通信的E2E测试可能难以并行化,进一步增加了执行的总时间。

如果测试运行时间过长且失败原因不明确,你正面临一个可能损害敏捷开发过程的瓶颈。花费在调试这些测试上的时间是本可以用于改进代码、重构组件或添加为业务带来价值的新功能的时间。

异步环境中失败的隐性成本

在具有异步通信的系统中调试失败是一项需要谨慎、耐心和结构化方法的挑战。确定失败根本原因的复杂性不仅影响开发时间,还会削弱工程师和质量分析师的积极性。缺乏问题来源的清晰性可能导致开发周期延长、团队挫败感增加,最终导致产品质量下降。

因此,计划端到端测试套件时,团队需要考虑这些挑战,并权衡测试的最佳方式。模拟在某些上下文中可能有用,但必须了解它们带来的局限性。最终目标始终是确保系统在现实世界中按预期工作,在那里异步通信和潜在错误是不可避免的。

价值交付延迟:端到端测试对开发周期的影响

当一个组织采用微服务架构时,主要目标之一是使不同团队能够独立工作,持续敏捷地交付价值。然而,在大型团队中,当多个团队可能在相互依赖的服务上工作时,端到端测试可能成为一个重要的争论点。尤其是当代码提交积压,等待通过E2E测试套件时,这导致了持续集成的延迟,从而影响了向客户交付新功能或修复的速度。

分布式环境中的端到端测试困境:利益冲突与不兼容性

想象一下一个大型公司(如果你还没有在其中工作),多个团队正在开发独立的服务,但这些服务需要集成以交付完整的功能。每个团队都提交了自己的代码,并且在任何东西发布到生产环境之前,必须运行端到端测试。如果其中一个测试失败,无论是由于配置问题、未解决的依赖关系,还是“Flaky 测试”,所有提交可能都将被搁置,直到问题解决。

这就形成了一个场景,一个团队的进展取决于另一个团队测试的成功。即使一个团队已经完成了工作,它也无法继续前进,除非另一个服务的测试通过。因此,向客户交付价值被延迟,持续集成的承诺受到影响。

这种情况可能会导致团队之间的利益冲突。例如,一个团队准备好发布其服务的新版本,但另一个团队仍在调整其E2E测试,以适应新功能或修复错误。这种不兼容可能导致显著延迟,代码已经准备好部署,但可能要等待几天甚至几周,直到所有团队达成一致。

Martin Fowler 在其关于持续集成的文章中指出,持续集成的目标是避免这种非集成代码的积累。他建议,持续集成的最大好处之一是尽早发现冲突和问题,但当E2E测试成为瓶颈时,这一好处就丧失了。相反,问题在流程的后期被发现,增加了解决它们所需的复杂性和时间。

一个现实的问题

想象一个团队正在开发一个新的多因素认证(MFA)登录功能,位于一个大型微服务系统中。安全团队已经实施并测试了MFA逻辑,但现在需要运行E2E测试,以确保这一新功能与所有其他服务(如账户管理、通知服务和支付系统)正常工作。

然而,E2E测试因MFA服务与通知系统之间的集成问题而失败,通知系统尚未更新以处理MFA发送的新消息。在这个问题解决之前,任何提交都无法进入生产。因此,所有依赖MFA的其他服务(如支付服务)也被阻塞。

这种延迟可能直接影响公司迅速响应合规要求的能力,不仅影响客户的价值交付,还影响整个系统的安全性。

对工程师和产品经理的影响

这种瓶颈对于工程师和产品经理、产品负责人来说都是令人沮丧的。对于工程师来说,当他们的工作因为不可控的问题而被阻碍时,这种感觉可能会让人沮丧,并导致注意力分散。相对于继续下一个任务,他们被困在解决通常与他们所开发的内容不直接相关的问题上。

对于产品经理和产品负责人来说,这些延迟可能会妥协截止日期和目标,使按时向客户交付价值变得更加困难。他们需要处理焦虑的利益相关者,重新规划发布,并可能调整开发优先级,所有这些都是由于开发周期后期出现的问题所致。

优化价值交付

使用端到端测试对于确保所有服务正常协作至关重要,但当这些测试成为瓶颈时,是时候重新考虑策略了。一个可能的解决方案是引入契约和集成测试,这些测试可以更孤立和高效地验证服务之间的交互,使团队能够独立前进,而无需等待E2E测试结果。

Michael Feathers 在《有效处理遗留代码》中提到,测试的真正有效性不在于一次性测试所有内容,而在于逐个验证每个组件是否在其上下文中得到验证。这可以减轻E2E测试的压力,确保它们仅用于验证关键业务流程,而不会阻碍持续交付价值。

发现错误的低效率:端到端测试的困境

端到端测试在检测错误方面效率低下的说法乍一看似乎自相矛盾。毕竟,这些测试全面覆盖了系统,模拟用户交互并验证完整的业务流程。然而,当从技术和业务角度分析时,这一看法变得更加合理。

端到端测试的复杂性与低效的错误检测

从技术角度来看,E2E测试无疑是编写和维护劳动密集型的工作。这是因为需要覆盖多个场景并确保系统组件之间的所有可能交互都得到了测试。然而,正是这种复杂性可能限制了其在检测错误方面的效率。

例如,一个表面上看似简单的功能——如更新用户个人信息——实际上可能包含许多需要考虑的业务规则。你是否曾经处理过这样的功能?看似容易,但深入代码后,你会发现有很多重要的检查不能被打破?例如,一个功能允许用户更新其地址,但前提是他们已验证身份,且仅在没有待处理交易的情况下才能更新。所有这些业务规则都需要测试,E2E测试必须涵盖所有这些条件。这意味着必须创建多个测试场景,每个场景都有其依赖关系和交互。

编写涵盖所有这些细微差别的E2E测试可能极为困难且耗时。即使测试编写得很好,它也可能仍无法捕捉某些行为,尤其是在特定或罕见情况下发生的行为。这可能导致尽管投入了大量精力来创建和维护这些测试,但检测到的错误数量较少。

从业务角度来看:业务规则和沟通的清晰性

E2E测试的效率还取决于业务规则的清晰性以及开发和质量团队之间的沟通是否顺畅。如果业务规则不明确,或者工程师和QA之间对于需要测试的内容没有共识,测试可能会变得表面化,无法捕捉关键细节。

在业务背景下,低效率的错误检测意味着关键问题可能会在进入生产环境之前未被发现,而在生产环境中修复这些问题的成本要高得多。此外,运行这些测试所投入的时间和资源可能无法得到回报,如果检测到的错误与投入的精力相比较少。

这就引发了一个重要问题:端到端测试是否真的确保软件质量的最佳方式?或者是否可以通过契约测试等其他策略来补充E2E测试,并提供一种更有效捕捉错误的方式?

Martin Fowler 的观点:契约测试作为补充

Martin Fowler 在其关于测试金字塔的文章中提出,一种平衡的方法可能比完全依赖端到端测试更有效。他引用契约测试作为一种补充策略。契约测试验证不同服务之间的交互,确保每个服务的期望得到满足。

这种方法在微服务架构中特别有用,在那里服务之间的通信可能非常复杂且容易出错。契约测试可以帮助在E2E测试失败之前捕捉到与集成问题相关的错误,使调试过程变得更简单、更高效。

编写真正有效的E2E测试需要对业务流程、可能的例外情况和边缘案例有深刻理解。尤其在复杂的系统中,这可能是一项重大的挑战。试图捕捉所有可能场景可能导致测试套件膨胀,许多用例被表面覆盖,却没有为验证过程真正增加显著价值。

因此,端到端测试在检测错误方面效率低下可能是由于多个因素的综合作用:技术复杂性、业务规则不明确以及编写有效覆盖所有可能场景的测试本质上的困难。


声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
150° /1506 人阅读/0 条评论 发表评论

登录 后发表评论