开发者自测试的困境:为何理论美好而实践艰难?

Ahmed El-Deeb
Amazon
Krausenstr. 38, 10117 Berlin
+49 176 434 28719
ahmed.eldeeb@qawithahmed.com
DOI: 10.1145/ 3780063.3780066

摘要

”我们将左移测试(将测试阶段前移到开发阶段)并缩减 QA,开发者将负责测试他们所发布的内容",这是我曾听到一位 CTO 宣布 QA 团队组织结构变革时的声明。这显然是一个自上而下的决定:房间里没有人(开发者、QA 工程师、SDM、TPM、PM 等)真正清楚这意味着什么,或者每个角色应该做什么来使其生效。这种假设——即开发者自测试能够开箱即用,甚至能提高质量标准——正是本文探讨的现象。为什么开发者自测试在理论上如此有吸引力,却在几乎每个实际实施中都表现不佳?问题不在于开发者自测试是一个有缺陷的想法,而在于它通常规划不当、方法错误。本文首先概述了来自行业的信号,展示了开发者自测试在实践中的失败方式和地点,然后分析了根本原因以及现有理论失效的点。最后,本文为软件工程研究和学术界提出了几项建议,说明他们如何更好地支持行业使开发者自测试作为一个社会技术系统取得成功。

1. 引言

许多公司认为由独立团队处理软件测试是一种开销。争论这是否合理不在本文讨论范围内。然而,正是基于这种信念,这些公司认为开发者除了功能开发外还应负责测试。这一运动被称为"开发者负责质量"——传达的意思是当开发者自己负责测试而不是由独立团队负责时,将激发他们对交付质量的所有权感。

当"开发者负责质量"时,他们通过测试对其交付的质量标准负责。对于每个功能,他们将编写测试用例来验证功能是否按预期工作,但更重要的是,他们需要尝试破坏它以验证其不可破坏性。这涉及测试操作系统、硬件规格和条件的组合。他们还需要以用户使用功能的方式思考,以便预测使用场景。

这些都是理论。然而,现实是软件工程师在执行额外的测试角色时面临重大挑战——至少在这种确保高质量标准的严谨性和强度水平上。在下一节中,我们将讨论来自行业的信号,告诉我们实践中的故事。接下来,我们将看到这一现实与我们理论上的开发者自测试理解有何不同。最后,我们将探讨如何弥合研究/学术界与实践之间的差距。

2. 关键行业信号

2.1 认知超载与交付压力

软件开发是一项复杂的任务。它需要解决问题的心理带宽和编码能力,以交付能够执行当今业务和客户高级用例的软件。更具挑战性的是,现代开发速度非常快。我们再也无法承受客户等待新功能或错误修复数月之久。在这种条件下,开发者忙于编码职责以实现功能并快速交付。在此基础上增加测试职责会导致要么在测试质量和深度上偷工减料,要么在交付生产力上打折扣。

实际上,组织的激励体系并不奖励开发者进行测试,而是奖励他们开发和交付功能。开发者的交付目标以及绩效评估取决于交付客户可见的功能;因此,开发者自然优先考虑编写新功能而不是编写测试。这给开发者增加了更多交付压力,消耗了更多心理带宽。为了完成任务,开发者需要花费大量时间处理实现复杂性、技术栈和架构设计。在这个过程中,他们还需要调试不工作的代码并审查同行代码。测试本身不是一项简单的任务,对认知要求很高。除了正常路径测试外,它还需要心智能力来阐述场景组合。这些场景不仅来自于理解实现代码,还来自于理解自己的代码如何与其他开发者编写的其他服务和组件以及整个产品交互。这是另一个需要心智能力的复杂层面。

切换到执行严格测试的上下文切换变得不简单。研究表明,频繁的中断或任务切换导致开发者"错过边缘情况、编写不完整的测试并引入微妙的错误"[1]。最终结果是次优的开发者自测试,无法达到预期的质量标准并使整个交付面临风险。

2.2 CI/CD 管道经常因非代码原因失败

测试不仅仅在创建后运行一次。拥有稳定的测试基础设施和 CI/CD 管道是成功执行和开发者信任的必须条件。然而,现实中测试基础设施故障、构建问题、不稳定测试、缓慢管道和延迟反馈很常见。一个开发者可以合并他们的代码,结果却被与他们尝试合并的代码无关的构建失败或测试失败所困扰。在这种情况下,他们必须离开主要任务并花时间排除这些故障,以便他们的合并能够通过。这导致更多流失,并将测试视为瓶颈而不是安全网。

微软和一些学术合作者进行了一项混合方法研究,探讨什么使开发者度过"糟糕的一天",排名第一的是:工具和基础设施问题——不稳定测试、缓慢管道、损坏的构建[2]

CI/CD 管道设计效率低下。管道随着多年来添加的多个阶段而分层,没有适当的设计、监控或随时间改进。检查、测试、扫描、构建、插件、库、依赖项等层层叠加,导致管道变慢或不稳定。许多公司的 CI 环境因缺乏单一所有权而遭受"公地悲剧"。没有人监控其性能并随时间改进。它被当作每个人都使用的公共资源,或许只是在失败并阻塞合并或发布过程时才跳上去处理。同样的所有权缺失导致了缺乏专门团队来负责设计管道、研究技术并随时间实施改进。随着时间的推移,出现了旨在解决工业问题的 DevOps 工具;然而,由于没有人拥有管道的监控和改进,这些优化从未被采用。在许多情况下,这也与代码和优先级有关。一些公司将内部环境和管道视为次于生产环境的二等公民。因此,他们给予更多关注和资源来维护生产环境,而留下测试基础设施。

我们告诉开发者拥有他们的测试,却给他们处理缓慢和脆弱的测试基础设施。编写测试已经是他们开发职责的开销,没有余地再因维护和处理不稳定基础设施而分心。

2.3 不稳定测试成为背景噪音

不稳定测试是那些没有产品错误而随机失败的测试。它们不一致;第一次运行失败,然后重试时通过,没有明显原因。或者它们由于非代码变更原因而失败,仅仅是由于其他测试相关问题,例如测试基础设施问题。当不稳定测试在许多组织中泛滥时,开发者学会不信任它们。例如,在谷歌,16%的测试表现出不稳定性[3]。这导致谷歌工程师表示,“当有误报历史时,忽略警报是人类的天性”[4]

除了可能导致不稳定测试的技术原因外,组织根本原因对产生不稳定测试的影响最大。正如我们在前一点讨论的,缺乏整个管道健康的端到端所有权是衡量管道健康和拥有改进步骤的差距。在许多情况下,管道涉及不同团队之间的多重所有权;然而,一个团队应负责监控整体健康并推动改进计划。团队通过遵循最小阻力路径来应对这一差距,要么完全跳过测试,要么不断重新运行它们。这种"重试直到变绿"的习惯剥夺了有效修复测试不稳定性的任何机会。CI 研究表明,开发者经常重新启动失败的构建而不是调查它;在大型 Travis CI 数据集中,至少 2%的构建由于怀疑不稳定性而被明确重新启动[5]。另一个导致不稳定性的重要原因是缺乏有效的可观察性。没有良好的可观察性,如日志和指标,团队无法找到不稳定性的实际根本原因。这与缺乏检测和分类不稳定性的工具相结合,使得修复不稳定测试的工作具有挑战性。谷歌内部工作称为"去不稳定化你的测试",强调自动检测和聚类不稳定测试并非易事,因此需要专门工具来定位大规模的根本原因[6]。没有这种能够管理不稳定性的工具,团队必须依赖自动化测试设计中的技能。而这里出现的挑战是,开发者在健壮的测试设计方面没有经过正式培训,尤其是在处理复杂的测试基础设施和技术栈时。开发者需要更长时间来解读不稳定性的根本原因,从而引入有效的解决方案来改进它们。

不稳定测试是开发者流失和不信任的第一大来源。开发者将不愿投入时间编写测试,因为他们知道这些测试注定会变得不稳定,成为瓶颈而不是支持快速交付的安全网。

2.4 社会技术摩擦

向开发者自测试的过渡不仅仅是技术变革。它也是文化和组织的变革。因此,它在不同层面产生摩擦。QA 专业人员感到他们的角色被贬低,安全感受到威胁,这导致抵抗和士气问题。另一方面,开发者感到他们被"本不属于协议一部分"的额外责任所负担。这可能导致连锁反应直至发布。曾经把关发布的 QA 现在感到权力被剥夺,可能仍感到需要维护控制,而曾经只是将代码"扔过篱笆"给 QA 的开发者可能不会站出来彻底测试。在激烈的摩擦中,当错误逃逸时,双方可能互相指责:我们是责怪开发者测试不足还是责怪 QA?

在没有整体质量战略的情况下进行这种转变会导致质量真空和激烈摩擦。许多公司认为转向开发者自测试只是让开发者承担测试任务。大多数公司缺乏能够预见并协调这一努力的 QA 经理角色。或者他们有这个角色但没有赋予其与开发经理合作建立端到端质量战略的权力,该战略由开发者自测试和 QA 负责的测试组成。

在没有明确指导、角色定义和整体质量战略的情况下,为开发者添加一个负责测试的 Jira 工单,就像要求开发者在没有导航系统的公海上航行一样。最终结果是努力白费,对该模式更加反感。

2.5 开发者缺乏测试设计的正式培训

开发者在软件测试方面存在技能差距,也缺乏适当水平的软件测试经验。这阻碍他们拥有测试思维或像测试人员一样思考。因此,他们只能考虑正常路径测试,这旨在验证他们的代码工作正常,而不是试图破坏它。这是两种完全不同的思维方式。最终结果是开发者只进行正常路径测试,而不涵盖负面条件。这导致不完整的测试,如果团队完全没有 QA 角色,这可能转化为影响客户体验的泄漏错误。

在大学的工程或计算机科学编程课程早期,项目交付更注重编码,而不是工业中开发者自测试文化所需的那种测试水平。在工作中,开发者期望交付功能而不是花大量时间测试它。这导致开发者缺乏适当的测试接触。他们没有获得学习时间或学徒期来学习和提高测试技能。

这导致挫败感:开发者负责测试,期望是他们交付无错误软件。随着项目变得更加复杂,开发者警告所需的测试复杂性水平。这与我们讨论的认知超载点相关,修正测试知识差距所需的额外努力导致开发者甚至不愿尝试,默认只是标记风险。

3. 理论失效之处:研究与实践的差距

理论期望当开发者负责测试时,会自动产生高质量。事实上,有些人认为这是获得高质量的唯一可能方式,因为在经典模型中,开发者可以仅仅责怪 QA 导致错误泄漏。当他们负责测试时,他们会在测试中表现出色,因为现在这是他们的责任。然而,现实告诉我们一个完整的故事。显然,这与所有权和指责游戏无关。这与执行的具体细节以及在全球端到端质量战略内适当协调测试工作有关。以下是理论在工业现实面前失效的地方:

  • 左移理想与期限和工具现实: 敏捷原则提倡早期测试,但在紧张的交付和复杂的软件开发下,开发者没有适当的带宽进行彻底测试。

  • 质量是每个人的责任……但没有人做: 许多组织取消了专门的 QA 角色,认为质量将成为每个人的工作。最终结果是质量真空和碎片化的质量战略,导致质量差距。理论将移除 QA 等同于消除孤岛,但实际上它往往移除了唯一超越正常路径思考的人。没有明确专注于质量的团队或个人,整体指标、风险分析、跨板质量标准、长期测试战略都会落空。

  • 开发者正常路径偏见: 当开发者负责测试时,现实是他们只会覆盖正常路径测试。开发者作为构建者的角色性质使他们从某物应如何工作的角度思考;然而,QA 工程师被训练思考什么可能出错以及如何破坏软件。这种思维方式对开发者来说不自然,需要培训和足够经验才能获得。

  • 激励错位: 理论假设当开发者负责测试时,他们会提高质量。然而,他们没有考虑组织中的激励结构。现实中,开发者因交付功能和达到交付目标而受到奖励。

  • 实现自动化 vs. 不稳定测试和基础设施: 当谈论开发者自测试时,理论是"我们将自动化一切",以便开发者可以在没有手动干预的情况下快速交付。现实中,大多数组织正在努力创建健壮的测试基础设施,并拥有坚实的工具和战略来对抗不稳定性。这减缓了开发者的速度并侵蚀了他们的信任。

  • 工具和环境差距: 理论假设有丰富的开发者测试工具和环境。然而,许多组织正努力为其复杂架构实现端到端测试。例如,优步发现许多微服务团队只编写了深度模拟的浅层单元测试[7]。他们不得不投资新的沙盒测试基础设施以使左移测试成为可能。

4. 软件工程研究的机会

为了解决面对真实行业信号时理论与实践之间的差距,研究以下主题的软件工程可以帮助行业解决其痛点:

  • 测试任务的认知负载建模: 需要正式模型和实证研究,探讨测试活动如何影响开发者的认知负载。例如,模型可以帮助识别团队的架构或过程何时在认知上要求太高而无法进行有效测试。

  • 质量工作的开发者激励结构: 学术界可以探索并提出与质量结果一致的开发者行为激励结构。这可能还涉及组织心理学和经济学,即公司如何以与功能交付一样有形的方式衡量和奖励质量贡献。

  • 分布式系统中的可调试性工程: 学术界可以大规模贡献可调试性框架、工具和方法论,使开发者能够更容易地测试和排除复杂分布式工作流的故障。这包括如何根本原因分析复杂系统中的问题,以了解出错原因并在未来改进。

  • 所有权过渡的组织动态: 学术界可以从传统 QA 模式向开发者自测试转变的社会技术变革中得出最佳实践。一个称为"质量文化变革"的框架可以作为公司的过渡工具包。通过案例研究、调查和访谈创建,这个工具包可以帮助公司处理诸如开发者抵抗、领导支持、沟通模式和培训计划等主题。

  • 测试稳定性工程和不稳定性研究: 不稳定测试被称为"工程中最昂贵的谎言",因为它们消耗生产力并增加成本。研究可以专注于自动不稳定性检测和分类。诸如自愈测试等主题可以变得更先进并大规模可用。此外,通过设计防止不稳定性的设计技术和在实现中增强稳定性。

  • 分布式系统的测试基础设施工程: 公司的组织结构非常复杂。虽然公司销售一种产品,但内部公司被构建为多个团队,每个团队独立运行自己的基础设施和技术栈。这种内部分层使得端到端测试和基础设施变得不可能。然而客户只看到一个产品,不关心公司内部如何构建。研究可以通过找到使多种技术栈之间接口成为可能的技术来提供帮助,以便团队可以构建支持自动化端到端测试的基础设施。

5. 结论

开发者自测试不是一个错误的想法或失败的想法。它只是在不考虑 QA 角色的情况下以一种不完整的方式被处理。没有明确的端到端质量战略将每个角色放在其在测试金字塔中最有效的位置,我们无法实现高质量标准而没有摩擦。没有仔细规划首先实现开发者自测试的倡议和项目,例如测试基础设施项目,我们正在带领团队走向更多挫败感。

开发者自测试也应被视为一个社会技术系统,一个涉及人员、流程和技术和谐工作的系统。这不是关于角色消除和职责从 QA 到开发者的转移。

参考文献

[1] Czerwinski, Mary, Eric Horvitz, and Susan Wilhite. “A Diary Study of Task Switching and Interruptions.” Proceedings of the SIGCHI Conference on Human Factors in Computing Systems, ACM, 2004, pp. 175–182.

[2] Meldiner, Ron. “Key Findings from New Research on Developer Productivity.” Faros AI Blog, Faros AI, 2024.

[3] Leong, Chaitanya, et al. “Assessing Transition-Based Test Selection Algorithms at Google.” 2019 IEEE/ACM International Conference on Software Engineering: Software Engineering in Practice (ICSE-SEIP), IEEE, 2019.

[4] Micco, John. “Flaky Tests at Google and How We Mitigate Them.” Google Testing Blog, 27 May 2016.

[5] Micco, John. “Flaky Tests at Google and How We Mitigate Them.” Google Testing Blog, 27 May 2016.

[6] Micco, John. “Flaky Tests at Google and How We Mitigate Them.” Google Testing Blog, 27 May 2016.

[7] Micco, John. “Flaky Tests at Google and How We Mitigate Them.” Google Testing Blog, 27 May 2016.

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐