测试驱动与行为驱动开发差异比较:有什么区别?

2021年11月27日22:43:03 发表评论 1,260 次浏览

测试驱动与行为驱动开发哪个更好测试驱动开发 (TDD)行为驱动开发 (BDD ) 都是软件开发的测试优先方法。他们共享共同的概念和范式,植根于相同的哲学。测试驱动与行为驱动开发有什么区别?在本文中,我们将重点介绍两种方法的共性、差异、优缺点。

什么是测试驱动开发(TDD)

测试驱动开发 (TDD) 是一种软件开发过程,它依赖于短开发周期的重复:需求变成非常具体的测试用例。编写代码是为了让测试通过。最后,重构和改进代码以确保代码质量并消除任何技术债务。这个循环就是众所周知的红-绿-重构循环。

什么是行为驱动开发(BDD)

行为驱动开发 (BDD) 是一种软件开发过程,它鼓励参与项目交付的所有各方之间进行协作。它鼓励使用各方都能理解的通用语言对系统行为进行定义和形式化,并将此定义用作基于 TDD 的流程的种子。

测试驱动与行为驱动开发差异比较:有什么区别?

TDD 和 BDD 之间的主要区别

TDD开发板
重点功能特性的交付实现预期的系统行为
方法自下而上或自上而下(验收测试驱动开发)自顶向下
初始点一个测试用例用户故事/场景
参与者技术团队包括客户在内的所有团队成员
编程语言通用语
过程精益、迭代精益、迭代
提供符合我们测试标准的功能系统一个按预期运行的系统和一个用人类通用语言描述系统行为的测试套件
避免过度设计、低测试覆盖率和低价值测试偏离预期的系统行为
脆性实现的改变可能导致测试套件的改变测试套件-仅在需要更改系统行为时才需要更改
实施难度自底向上比较简单,自顶向下比较困难所有相关方的更大学习曲线

测试驱动开发 (TDD)

测试驱动与行为驱动开发差异比较:在 TDD 中,我们有众所周知的 Red-Green-Refactor 循环。我们从一个失败的测试(红色)开始,并尽可能少地执行必要的代码以使其通过(绿色)。此过程也称为测试优先开发。TDD 还添加了一个重构阶段,这对整体成功同样重要。

TDD 方法是由 Kent Beck 发现(或重新发现)的,他是单元测试和后来的 TDD、敏捷软件开发以及最终的极限编程的先驱之一。

测试驱动与行为驱动开发有什么区别?下图很好地提供了一个易于理解的过程概述。然而,美在于细节。在深入研究每个单独的阶段之前,我们还必须讨论 TDD 的两种高级方法,即自底向上和自顶向下 TDD。

测试驱动与行为驱动开发差异比较:有什么区别?
图 1:TDD 的红绿重构循环

自下而上的 TDD

自下而上 TDD(也称为 Inside-Out TDD)背后的想法是迭代地构建功能,一次专注于一个实体,在转移到其他实体和其他层之前巩固其行为。

我们从编写单元级测试开始,继续执行它们,然后继续编写更高级别的测试,这些测试聚合低级测试的功能,创建所述聚合测试的实现,等等。通过逐层构建,我们最终将进入聚合测试是验收级别测试的阶段,希望与所请求的功能保持一致。这个过程使它成为一种高度以开发人员为中心的方法,主要是为了让开发人员的生活更轻松。

优点缺点
一次专注于一个功能实体延迟整合阶段
功能实体易于识别实体需要暴露的行为数量不清楚
不需要高层次的眼光就可以开始实体之间不能正确交互的高风险因此需要重构
帮助并行化业务逻辑可能分布在多个实体中,使得测试不明确和困难
测试驱动与行为驱动开发差异比较

自上而下的 TDD

自上而下的 TDD 也称为外向内 TDD 或验收测试驱动开发 (ATDD)。它采取相反的方法。我们开始构建一个系统,迭代地向实现添加更多细节。并且随着重构机会变得明显,迭代地将其分解为更小的实体。

我们首先编写一个验收级别的测试,然后进行最少的实现。这个测试也需要逐步进行。因此,在创建任何新实体或方法之前,需要先进行适当级别的测试。因此,我们迭代地完善解决方案,直到它解决了启动整个练习(即验收测试)的问题。

测试驱动与行为驱动开发哪个更好?这种设置使自上而下的 TDD 成为一种更加以业务/客户为中心的方法。这种方法更具有挑战性,因为它在很大程度上依赖于客户和团队之间的良好沟通。它还需要开发人员具有良好的公民意识,因为需要仔细考虑下一个迭代步骤。这个过程会及时加速,但确实有一个学习曲线。然而,好处远远超过任何负面影响。这种方法导致客户和团队之间的协作成为中心舞台,一个具有非常明确的行为、明确定义的流程、首先关注集成以及非常可预测的工作流程和结果的系统。

优点缺点
一次关注一个用户请求的场景正确进行断言测试至关重要,因此需要业务/用户/客户和团队之间的协作讨论
流量易于识别依赖于 stubbing、mocking 和/或测试替身
重点是集成而不是实现细节由于流程是通过多次迭代确定的,因此启动速度较慢
实体需要公开的行为数量是明确的更有限的并行化机会,直到骨架系统开始出现
用户需求、系统设计和实现细节都清楚地反映在测试套件中 
可预测的 
测试驱动与行为驱动开发差异比较

红绿重构生命周期

有了上面讨论的如何处理 TDD 的高级愿景,我们可以自由地深入研究 Red-Green-Refactor 流程的三个核心阶段。

红色

我们首先编写一个测试,执行它(因此失败),然后才开始执行该测试。编写正确的测试在这里至关重要,就我们试图实现的测试层达成一致也是如此。这是验收级别测试还是单元级别测试?这种选择是自下而上和自上而下 TDD 之间的主要划分。

绿色

在绿色阶段,我们必须创建一个实现来使红色阶段中定义的测试通过。实现应该是尽可能最少的实现,使测试通过,仅此而已。运行测试并观察它通过。

创建尽可能最少的实现通常是这里的挑战,因为开发人员可能倾向于通过习惯的力量立即修饰实现。这种结果是不可取的,因为它会产生技术包袱,随着时间的推移,会使重构更加昂贵,并且可能会根据重构成本来扭曲系统。通过使每个实施步骤尽可能小,我们进一步强调了我们试图实施的过程的迭代性质。此功能将赋予我们敏捷性。

另一个关键方面是红色阶段,即测试,是驱动绿色阶段的因素。不应该有不是由非常具体的测试驱动的实现。如果我们遵循自下而上的方法,这几乎是自然而然的。但是,如果我们采用自上而下的方法,那么我们必须更加认真,并确保在实现形成时创建进一步的测试,从而从验收级别测试转移到单元级别测试。

重构

重构阶段是 TDD 的第三个支柱。这里的目标是重新审视和改进实施。优化了实现,提高了代码质量,消除了冗余。

重构对许多人来说可能具有负面含义,被视为纯粹的成本,修复第一次做不当的事情。这种看法起源于更传统的工作流程,其中重构主要仅在必要时进行,通常是在技术包袱达到无法维持的水平时,从而导致冗长、昂贵的重构工作。

然而,在这里,重构是工作流的一个固有部分,并且是迭代执行的。这种灵活性极大地降低了重构的成本。代码没有完全重新设计。相反,它正在缓慢发展。此外,根据定义,重构后的代码包含在测试中。在代码的前一次迭代中已经通过的测试。因此,可以放心地进行重构,从而进一步加快速度。此外,这种改进代码库的迭代方法允许紧急设计,这大大降低了过度设计问题的风险。

行为不应该改变是至关重要的,我们不会在重构阶段添加额外的功能。这个过程允许以极大的信心和敏捷性完成重构,因为根据定义,相关代码已经被测试覆盖。

测试驱动与行为驱动开发差异比较:有什么区别?

行为驱动开发 (BDD)

测试驱动与行为驱动开发有什么区别?如前所述,TDD(或自底向上 TDD)是一种以开发人员为中心的方法,旨在生成更好的代码库和更好的测试套件。相比之下,ATDD 更以客户为中心,旨在提供更好的整体解决方案。我们可以将行为驱动开发视为 ATDD 的下一个逻辑进展。Dan North在 TDD 和 ATDD 方面的经验导致他提出了 BDD 概念,他的想法和主张是将 TDD 和 ATDD 的最佳方面结合在一起,同时消除他在这两种方法中确定的痛点。他发现具有描述性的测试名称很有帮助,并且测试行为比功能测试更有价值。

Dan North 在简洁地将 BDD 描述为“使用多个级别的示例来创建共享理解和表面确定性以交付重要的软件”方面做得非常出色

这里的一些关键点:

  • 我们关心的是系统的行为
  • 测试行为比测试具体的功能实现细节更有价值
  • 使用通用语言/符号来发展跨领域专家、开发人员、测试人员、利益相关者等对预期和现有行为的共同理解。
  • 当每个人都可以理解系统的行为、已经实现的内容和正在实现的内容并且系统保证满足所描述的行为时,我们就实现了表面确定性

测试驱动与行为驱动开发差异比较:BDD 将更多的责任放在客户和团队之间富有成效的协作上。正确定义系统的行为变得更加重要,从而导致正确的行为测试。这里的一个常见陷阱是对系统将如何实现行为做出假设。此错误发生在带有实现细节的测试中,因此使其成为功能测试而不是真正的行为测试。这个错误是我们想要避免的。

行为测试的价值在于它测试系统。它不关心它如何实现结果。此设置意味着行为测试不应随时间变化。除非行为本身需要作为功能请求的一部分进行更改。与功能测试相比,成本效益更为重要,因为此类测试通常与实现紧密结合,以至于代码的重构也涉及测试的重构。

然而,更实质性的好处是保留了表面确定性。在功能测试中,代码重构也可能需要测试重构,这不可避免地导致信心的丧失。如果测试失败,我们不确定可能是什么原因:代码、测试或两者兼而有之。即使测试通过,我们也不能确信之前的行为已经被保留。我们所知道的是测试与实现相匹配。这个结果价值不高,因为归根结底,客户关心的是系统的行为。因此,我们需要测试和保证的是系统的行为。

基于 BDD 的方法应该导致完整的测试覆盖,其中行为测试使用通用语言向所有各方完整描述系统的行为。与功能测试相比,即使完全覆盖也不能保证系统是否满足客户的需求,重构测试套件本身的风险和成本只会随着覆盖范围的扩大而增加。当然,通过从行为测试到更多功能测试的自上而下的工作来利用这两者将赋予行为测试的表面确定性好处。此外,功能测试的以开发人员为中心的好处也抑制了功能测试的成本和风险,因为它们只在适当的地方使用。

直接比较TDD和BDD,主要的变化是:

  • 简化了测试内容的决定;我们需要测试行为
  • 我们利用一种通用语言来缩短另一层通信并简化工作;利益相关者定义的用户故事是测试用例

出现了一个框架和工具生态系统,以允许跨团队基于通用语言的协作。以及通过利用行业标准工具集成和执行测试等行为。这方面的例子包括 Cucumber、JBehave 和 Fitnesse,仅举几例。

测试驱动与行为驱动开发差异比较:有什么区别?

工作的正确工具

测试驱动与行为驱动开发哪个更好?正如我们所见,TDD 和 BDD 并不是真正相互直接竞争。将 BDD 视为 TDD 和 ATDD 的进一步演变,它带来更多以客户为中心的内容,并进一步强调客户与技术团队在流程各个阶段之间的沟通。这样做的结果是一个系统,其行为符合所有相关方的预期,以及一个测试套件,该测试套件以每个人都可以访问并易于理解的人类可读方式描述系统的许多行为的整体。反过来,该系统不仅对已实施的系统而且对系统的未来更改、重构和维护提供了非常高的信心。

测试驱动与行为驱动开发有什么区别?同时,BDD 很大程度上基于 TDD 流程,但有一些关键的变化。虽然客户或团队的特定成员可能主要参与系统的最顶层,但其他团队成员(如开发人员和 QA 工程师)会在他们以顶层方式工作时有机地从 BDD 转变为 TDD 模型。下来时尚。

我们期望获得以下主要好处:

  • 带来痛苦
  • 客户与团队协作的责任
  • 客户和团队之间共享的共同语言,以共享理解
  • 强加精益的迭代过程
  • 保证交付的软件不仅可以工作,而且可以按定义工作
  • 通过紧急设计避免过度工程,从而通过尽可能最小的解决方案达到预期的结果
  • 表面确定性允许快速和自信的代码重构
  • 测试具有与生俱来的价值 VS 创建测试只是为了满足任意代码覆盖率阈值
  • 测试是完整描述系统行为的活文档

测试驱动与行为驱动开发差异比较总结:在某些情况下,BDD 可能不是合适的选择。在某些情况下,所讨论的系统技术性很强,可能根本就不是面向客户的。它使需求与功能的联系比与行为的联系更紧密,使 TDD 可能更适合。

采用 TDD 还是 BDD?

测试驱动与行为驱动开发哪个更好?最终,问题不应该是采用 TDD 还是 BDD,而是哪种方法最适合手头的任务。很多时候,这个问题的答案是两者兼而有之。随着越来越多的人参与到更重要的项目中,不言而喻的是,在整个项目生命周期的不同级别和不同时间需要这两种方法。TDD 将为技术团队提供结构和信心。BDD 将促进和强调所有相关方之间的沟通,并最终交付满足客户期望的产品,并提供所需的表面确定性,以确保对未来进一步发展产品的信心。

通常情况下,这里没有灵丹妙药。相反,我们拥有的是一些非常有效的方法。两者的知识将使团队能够根据项目的需要确定最佳方法。进一步的经验和执行的流动性将使团队能够在整个项目生命周期中出现需求时使用其工具箱中的所有工具,从而实现最佳的业务成果。要了解这如何适用于你的业务,请立即咨询我们的一位专家。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: