端到端测试已被广泛采用,作为在复杂系统(尤其是微服务架构)中确保质量的关键策略。端到端测试承诺验证完整的业务流程,并在问题到达生产环境之前发现错误,这使得许多公司大力投资于此策略。然而,随着这些系统复杂度的增加,服务之间的相互依赖性变得更加复杂,端到端测试开始暴露其局限性。
在本文中,我们将讨论在微服务环境中完全依赖端到端测试所带来的问题。我们将探讨反馈等待时间过长、测试不稳定、高维护成本以及调试困难如何削弱开发团队的敏捷性和效率。此外,我们还将看到,交付价值的减缓、发现错误的低效率以及生产环境中持续出现的错误,进一步凸显了重新思考这种策略的必要性。
如果你曾经好奇为什么你的测试流水线会拖慢交付速度,或者为什么错误仍然会悄然进入生产环境,那么这篇文章就是为你而写的。
软件开发的核心目的
当我们讨论软件工程中的质量时,往往将其理解为没有错误或遵守技术规范。然而,这种狭隘的观点忽略了真正使数字产品具有价值的基本方面。质量不仅仅是技术正确性,还涉及到软件有效解决实际问题、提供积极的用户体验以及满足业务期望的能力。
“质量”一词源自拉丁语“qualitas”,由“qualis”衍生,意思是“什么样的”或“什么性质的”。最初,它指的是定义某物本质的属性或特性。随着时间的推移,质量的概念演变为不仅代表产品的内在属性,还代表其生成价值和满足期望的能力。
尽管许多数字产品可能拥有相同的终极解决方案目标(如为一群用户解决特定问题或满足业务需求),但每个产品的质量可能差异显著。数字产品的质量不仅取决于其实现最终目标的能力,还取决于它实现目标的方式。不同的产品可能解决相同的问题,但它们的实现方式——为用户提供的体验、效率、可靠性、美学和其他因素——能够区分一个产品与另一个产品。
对于一小部分(我相信)软件工程师、业务分析师甚至管理者来说,质量可能被错误地视为敏捷性的障碍。这是因为确保质量的过程本质上是严谨和细致的。它不仅包括测试和验证,还包括不断的审查、调整,有时甚至是返工。从表面上看,这个过程似乎是推迟开发和交付新功能的原因。
但这种观点忽略了一个至关重要的点:质量不仅仅是测试发现缺陷,而是确保交付的产品真正满足用户和业务的期望。一个快速推出但未能兑现承诺的系统并没有带来价值——而在发布后修复这些缺陷的成本显著高于在开发期间防止它们所花费的时间。
想象一下汽车。每当汽车制造商推出新车型时,车辆在上市前都会经过一系列严格的测试——碰撞测试、安全测试、不同条件下的性能测试。这些测试并不是为了推迟汽车的发布,而是为了确保一旦交到消费者手中,汽车是安全、可靠且能够满足未来车主的期望的。
然而,当制造商未能在发布前确保质量时,后果可能非常严重。车辆投入使用后发现问题通常会导致召回——这是一项复杂的流程,涉及找到所有受影响的车辆、执行修复或更换以及管理客户的不满。召回的典型步骤包括:
- 问题识别:发现影响车辆安全或功能的缺陷。
- 与车主沟通:通知车主问题以及需要采取的纠正步骤。
- 执行修复:组织维修或更换,可能涉及将车辆送至经销商或授权维修店。
- 管理成本:承担维修、物流成本,可能还需赔偿消费者。
- 恢复信任:努力恢复受影响消费者的信任,这可能包括解决他们的失望和对车辆可能存在其他问题的担忧。
对于涉及召回的车辆车主来说,这一过程往往会引发一种混合的挫折感和担忧。除了必须将车送修的不便之外,还有对未来可能出现其他问题的恐惧,这可能动摇了他们对品牌的信任。对于汽车制造商来说,召回不仅是一个巨大的财务负担,也是对其声誉的打击。
类似地,在软件工程中,测试是确保最终产品坚固、可靠和有价值的重要组成部分。如果我们未能在发布前确保这一质量,后果(例如生产中的错误、安全故障和用户信任的丧失)可能与汽车行业的召回带来的影响相当。
软件工程师兼测试专家詹姆斯·巴赫(James Bach)定义了软件测试:“测试是质疑产品以评估其质量的过程。”换句话说,测试是我们用来挑战软件的工具,通过在不同情况下对其进行测试,确保它能够应对现实世界中的挑战。
当开发新功能时,它必须经历自己的“碰撞测试”。我们不仅应在理想条件下测试它,还应在不利情况下测试——如高用户负载、网络故障、与其他系统的集成——以确保它足够坚固,能够应对这些挑战。这些测试不应被视为延迟,而应被视为对产品质量的投资,从而扩展至业务的成功。
因此,软件工程中测试的真正目的是确保每个交付的功能都已准备好应对现实世界的挑战。测试的存在不是为了阻碍或减缓开发,而是为了确保当功能到达最终用户时,它将符合预期并能够交付预期的价值。当我们以这种方式理解测试时,很明显它是敏捷性和产品成功的盟友,而不是敌人。
发现阶段在产品质量中的重要性
在编写任何一行代码之前,软件开发中有一个关键阶段:发现阶段。在此阶段,业务专家、产品负责人和软件工程师共同探索并深入理解需要解决的问题。这是明确解决方案目标并确定如何为业务和用户创造真正价值的地方。
一个很好的类比是建筑物的建造。想象一个工程团队正在建造一座摩天大楼。在铺设任何砖块之前,需要进行紧密的规划和工程工作,以确保基础足够坚固以支撑结构。如果基础设计或构造不当,无论上层建筑多么完美,整座建筑都将处于危险之中。同样,在软件开发中,发现阶段就像基础:在这里,明确定义了软件应该是什么以及它应该如何工作。
明确理解问题和目标对于确保最终产品的高质量至关重要。如果缺乏基于研究和证据的明确需求,开发的任何解决方案都可能偏离方向,无法满足业务或用户的实际需求。因此,质量从测试阶段开始得很早;它植根于发现阶段的思考和分析质量。
在此阶段,软件工程师应积极参与,与业务专家和产品负责人紧密合作。他们带来了技术视角,帮助塑造所提出解决方案的可行性,并确保需求清晰、现实且可实现。如果没有这种密切合作,误解和期望不一致的风险将显著增加,这可能会影响最终产品的质量。
当发现阶段执行良好时,所有相关人员都对问题及解决方案的目标有了深刻理解,软件开发就建立在坚实的基础上。这反过来促进了产品的创建,不仅能履行其功能,还能以对业务和用户真正有意义的方式增值。
因此,在考虑测试或敏捷交付之前,必须记住,质量始于结构良好的发现阶段。正如汽车需要经过严格测试以确保其安全性和性能,软件也必须从一开始就经过坚实的规划和验证,确保每个功能能够以高效且相关的方式为业务和最终用户增值。
那么端到端测试的角色是什么?
随着在发现阶段奠定了坚实的基础,软件开发可以在明确的方向和目的感下进行。但即便所有努力都确保规划周全,仍有必要验证开发的解决方案是否真正提供了所承诺的价值。这就是端到端(E2E)测试的作用所在。
E2E测试旨在验证系统的所有组件是否按预期协同工作,确保业务流程从头到尾都能正常运行。在微服务系统中,这些测试对于发现仅在所有服务同时运行时才会出现的问题尤为重要,它们模拟了最终用户的体验。
然而,尽管E2E测试至关重要,但它们并非没有挑战。当实施不当或过度时,它们可能成为软件开发和交付流程中的一个显著瓶颈。协调多个服务和系统的需求可能导致测试变得缓慢、不稳定且难以维护。此外,在复杂的架构中,获取反馈所需的时间可能很长,反过来会削弱团队的敏捷性。
另一个关键点是,尽管E2E测试旨在涵盖完整的业务流程,但它们可能无法精确定位问题的根源。当E2E测试失败时,可能很难确定问题出在特定服务中、服务之间的通信中,还是系统中的其他地方。这可能导致漫长且令人沮丧的调试过程,通常会导致返工并普遍减缓交付进度。
因此,尽管E2E测试在验证复杂系统中起着重要作用,但必须谨慎使用。它们的实施应与其他形式的测试(如单元测试、集成测试和契约测试)相平衡,这些测试可以更快、更孤立地对系统的特定组件进行反馈。当这些不同类型的测试有效结合时,它们可以提供全面的覆盖,而不损害敏捷性。让我们深入探讨这一点。
理解端到端测试的关键考量
测试是我们用来验证软件可观察行为的工具,即我们开发的解决方案是否真正实现了其预期目的。这包括测试功能是否符合业务需求、提供令人满意的用户体验,并在技术上是可靠的。要确保可观察行为是正确的,我们必须像对待软件本身一样对待测试的质量。这适用于所有类型的测试,无论是单元测试、验收测试、契约测试还是端到端测试。
每种测试策略都有其优势和劣势,正确地运用它们至关重要。例如,单元测试提供快速反馈并隔离特定组件中的问题,但它们无法捕捉集成故障。验收测试验证软件是否满足业务需求,但它们可能无法涵盖所有技术细节。契约测试确保服务之间的通信正确,但不能保证系统的完整行为。而尽管端到端测试对于验证完整流程至关重要,但如果使用不当,它们可能会成为陷阱。
我们希望避免这些陷阱,以保持向业务交付价值的敏捷性。因此,重要的是理解,尽管端到端测试起着重要作用,但它们并非最终策略,必须谨慎使用。
在这个背景下,让我们聚焦于在盲目相信端到端测试是最终解决方案时,我们可能面临的一些常见陷阱。我们将探讨八个需要特别注意的关键点:
- 反馈等待时间过长:随着端到端测试套件的增长,完整执行测试所需的时间也随之增加。这意味着工程师需要更长时间才能获得对其更改的反馈,这可能会延迟开发并降低团队效率。
- 对结果缺乏信心:不稳定的测试,即所谓的“Flaky测试”,是一个重大挑战。它们可能对相同代码产生不同的结果,导致需要重新运行测试以确认是否真的存在问题。这会削弱对测试套件的信心,并可能消耗宝贵的时间和资源。
- 高维护成本:维护一个稳定一致的测试环境是一项艰巨的任务,尤其是在需要频繁手动配置的系统中。任何手动更改都可能破坏测试数据或环境条件,使测试的维护变得昂贵且费力。
- 难以确定失败原因:在异步通信盛行的环境中,调试测试失败可能变得极其复杂。通常很难将失败与其真实原因(例如消息未发送到队列)联系起来,导致系统其他部分出现意外行为。这使得找出问题变得更加困难。
- 价值交付延迟:当代码提交堆积等待通过端到端测试套件时,部署流程可能会显著延迟。这种持续集成的延迟可能会减少交付频率,减缓向客户交付新功能或修复的速度。
- 发现错误的低效率:尽管广泛覆盖并与系统交互,端到端测试并不总是有效地发现与业务预期不一致的行为。在某些情况下,即使执行多次,检测到的失败数量与投入的时间和精力相比可能不成比例,这让人对这种方法的效率产生质疑。
在接下来的章节中,我们将深入探讨每个问题,讨论在具有复杂集成、持续异步通信以及多种业务规则的分布式环境中应采取的预防措施。
反馈等待时间过长:对工程团队的影响
随着端到端(E2E)测试套件的扩展,执行它们所需的时间呈指数级增长。这种执行时间的增加不仅是一个技术问题;它深刻影响了工程团队、产品经理、产品负责人、执行人员和QA专业人员的工作动态。为了更好地理解其影响,我们需要考虑所涉及的因素:时间、价值和敏捷性。
涉及什么?
在软件开发中,快速反馈至关重要。E2E测试旨在验证整个系统的行为,确保所有组件正确交互。然而,随着系统的复杂性增加,更多的测试被添加到套件中,这自然导致执行时间的增加。
《微服务模式》的作者Chris Richardson强调,在微服务架构中,验证不同服务之间的集成需求可能会生成大量测试用例。架构中引入的每个新服务都会增加端到端测试的需求,以确保它与其他服务正确协作。这可能导致一个覆盖广泛的E2E测试套件,尽管它覆盖了许多内容,却成为一个瓶颈,拖延部署并削弱了微服务的主要优势之一:敏捷性。
Richardson评论说:“端到端测试通常是一个瓶颈,它减少了部署频率,抵消了使用微服务的目的。你有一个单体——部署单元——由多个服务组成。换句话说,就是一个分布式单体。”这一关键观点强调了端到端测试的滥用或过度使用如何将本应敏捷和模块化的架构转变为伪装的单体。
敏捷开发和持续测试的主要倡导者之一Martin Fowler也指出,“测试是质量的基石,但如果管理不当,这块基石可能变成负担。”当端到端测试规模不当或过度依赖时,它们可能会产生正如Richardson提到的瓶颈,导致一个速度和灵活性被牺牲的系统。
Fowler更进一步,建议不平衡的测试方法可能会导致端到端测试数量膨胀,最终这些测试成为负担而非益处。他指出,测试金字塔越高,测试数量应越少。这意味着作为高级测试的E2E测试应尽量减少使用。
Fowler警告说,过多的E2E测试可能表明测试流程臃肿,导致测试套件缓慢、脆弱且维护成本高昂。
这种测试套件的持续扩展会形成一个循环,反馈时间延长,导致工程师不得不等待很长时间才能确认他们的更改未引入新问题。这种延迟直接影响团队的工作流程,并可能带来一系列负面影响。
对软件工程师的挑战
对于软件工程师来说,时间是一个至关重要的资源。当进行更改时,理想的情况是几乎立即获得反馈。这使得可以在变更仍然清晰可见时快速调整。然而,当E2E测试套件需要数小时执行时,反馈被延迟,迫使工程师将注意力转向其他任务,等待结果。这种情况引入了若干挑战:
- 上下文丢失:当反馈缓慢时,工程师可能会失去对所做更改的上下文。这意味着如果发现问题,他们需要花时间回忆所做的更改及其原因,从而降低效率。
* 多任务低效:为了绕过等待时间,工程师可能会尝试在等待反馈时进行其他任务,但这可能导致低效的多任务处理。频繁在复杂任务之间切换会降低工作质量,并增加错误的风险。
- 错误修复延迟:如果经过长时间等待后发现失败,立即纠正变得困难,导致更多时间用于识别和修复问题,从而延迟开发进度。
对产品经理和产品负责人的影响
对于产品经理和产品负责人来说,敏捷地交付新功能和修复对于保持竞争力和满足市场需求至关重要。当端到端测试反馈缓慢时,开发和部署周期被拉长。这可能会带来若干后果:
- 敏捷性降低:快速响应市场变化或新的用户见解的能力受到限制。功能交付时间延长,可能会错失机会。
- 规划受阻:反馈周期延长使得开发下一步的规划更加困难,因为时间估算变得不再准确。这会影响与利益相关者的沟通,并危及交付时间。
- 基于过时数据做决策:反馈延迟可能意味着决策基于已发生变化的情况和数据做出,导致做出不太明智的选择。
对QA和执行人员的挑战
对于负责确保最终产品质量的QA专业人员来说,维护稳定且可靠的测试环境的挑战更为显著。当反馈缓慢时,他们有更少的时间识别并报告问题,影响了下一次迭代开始前的检测效果。这可能导致测试效率下降,增加生产中出现未检测到问题的风险。
执行人员则更加关注效率和投资回报率(ROI)。缓慢的反馈周期可能意味着更高的开发成本和团队效率下降,最终影响公司的财务表现。此外,开发周期的延迟可能影响公司在市场中的声誉,尤其是如果竞争对手更为敏捷。
失去时间、价值和敏捷性
等待端到端测试反馈所失去的时间,本可以用于创造新功能、改进产品或修复问题。这降低了工程团队的敏捷性,削弱了他们快速交付价值的能力。敏捷开发基于短反馈周期的前提,能够快速、频繁地进行迭代。当反馈延迟时,快速迭代的能力受到了限制,这可能导致产品在市场上缺乏竞争力或不适应市场需求。
再引用软件顾问兼作者Chris Richardson的警告:
“端到端测试可能成为一个显著的瓶颈,尤其是在服务之间的相互依赖性增加时,情景和流程的复杂性也随之增加。”
如果不加以管理,这种复杂性可能会将一个本应确保质量的测试套件转变为一个阻碍敏捷性和持续交付价值的障碍。
Richardson还指出,许多组织依赖端到端测试,是因为他们发现服务级别的测试不足以确保应用程序的正确性。然而,他强调,这通常是架构有缺陷的症状,服务设计无法独立部署,导致需要一个E2E套件,在实践中创建了一个“分布式单体”。他建议,与其盲目依赖E2E测试,解决方案是修复架构,减少服务数量,并确保每个服务可以独立部署。
Martin Fowler在其关于持续集成的文章中也强调了“优化快速反馈”的重要性。他认为,没有快速反馈,团队应对问题和高效迭代的能力将受到严重限制。他主张使用测试金字塔,测试的基础应该是单元测试——速度快且成本低——而端到端测试则应减少以避免这些瓶颈。
快速反馈的概念并不新鲜,但它的重要性不可低估。在一个需要快速决策和敏捷实施变更的环境中,端到端测试的缓慢反馈会让开发过程陷入停滞。当反馈快速时,工程师可以立即采取行动,修复问题,调整功能并继续前进。这保持了工作流程的顺畅,并使产品能够持续演变,保持相关性和竞争力。