BDD - 测试驱动开发



当您查看任何关于行为驱动开发的参考资料时,您会发现诸如“BDD 源于 TDD”、“BDD 和 TDD”之类的短语。要了解 BDD 的起源,为什么说它源于 TDD,以及 BDD 和 TDD 是什么,您必须了解 TDD。

为什么要测试?

首先,让我们深入了解测试的基础知识。测试的目的是确保所构建的系统按预期工作。请考虑以下示例。

Testing

因此,根据经验,我们了解到在发现缺陷时立即修复它在成本效益方面会更高。因此,有必要在开发和测试的每个阶段编写测试用例。这就是我们传统的测试实践所教给我们的,通常被称为尽早测试。

Exploratory Testing

这种测试方法被称为最后测试方法,因为测试是在某个阶段完成后进行的。

最后测试方法的挑战

在软件开发项目中,最后测试方法已经沿用了一段时间。然而,实际上,由于这种方法需要等到特定阶段完成后才能进行测试,因此经常由于以下原因而被忽视:

  • 阶段完成的延迟。

  • 紧张的时间安排。

  • 专注于按时交付,跳过测试。

此外,在最后测试方法中,应该由开发人员完成的单元测试经常被跳过。发现的各种原因都基于开发人员的心态:

  • 他们是开发人员,而不是测试人员。

  • 测试是测试人员的责任。

  • 他们在编码方面很有效率,他们的代码不会有缺陷。

这导致:

  • 影响交付产品的质量。

  • 仅将质量责任归咎于测试人员。

  • 修复缺陷的成本很高,交付后。

  • 无法获得客户满意度,这也意味着失去回头客,从而影响信誉。

这些因素促使了范式的转变,从而专注于测试。结果是首要测试方法。

首要测试方法

首要测试方法将由内而外(编写代码然后测试)的方式替换为由外而内(编写测试然后编写代码)的开发方式。

这种方法被整合到以下软件开发方法中(也是敏捷方法):

  • 极限编程 (XP)。

  • 测试驱动开发 (TDD)。

在这些方法中,开发人员在编写代码模块的任何一行代码之前,都会设计和编写该代码模块的单元测试。然后,开发人员创建代码模块,目标是通过单元测试。因此,这些方法使用单元测试来驱动开发。

需要注意的基本点是,目标是基于测试的开发。

红-绿-重构循环

测试驱动开发用于在单元测试的指导下开发代码。

**步骤 1** - 考虑要编写的代码模块。

**步骤 2** - 编写测试

**步骤 3** - 运行测试。

测试失败,因为代码尚未编写。因此,步骤 2 通常被称为编写失败的测试。

**步骤 4** - 编写尽可能少的代码以通过测试。

**步骤 5** - 运行所有测试以确保它们仍然全部通过。单元测试是自动化的,以方便此步骤。

**步骤 6** - 重构。

**步骤 7** - 对下一个代码模块重复步骤 1 到步骤 6。

每个循环都应该非常短,一个典型的小时内应该包含许多循环。

Red Green Refactor Cycle

这也被称为**红-绿-重构**循环,其中:

  • **红色** - 编写失败的测试。

  • **绿色** - 编写代码以通过测试。

  • **重构** - 删除重复项并将代码改进到可接受的标准。

TDD 流程步骤

下图说明了 TDD 流程的步骤。

TDD Process Steps

TDD 的优势

测试驱动开发的好处或优势是:

  • 开发人员需要首先了解期望的结果以及如何在创建代码之前对其进行测试。

  • 只有当测试通过且代码经过重构后,组件的代码才算完成。这确保了在开发人员转到下一个测试之前进行测试和重构。

  • 由于在每次重构后都会运行单元测试套件,因此每个组件仍然可以工作的反馈是持续的。

  • 单元测试充当始终最新的动态文档。

  • 如果发现缺陷,开发人员会创建一个测试来揭示该缺陷,然后修改代码以使测试通过并修复缺陷。这减少了调试时间。所有其他测试也会运行,当它们通过时,确保现有功能不会中断

  • 开发人员可以随时做出设计决策和重构,运行测试可以确保系统仍在工作。这使得软件易于维护。

  • 开发人员有信心进行任何更改,因为如果更改影响任何现有功能,运行测试会揭示这一点,并且可以立即修复缺陷。

  • 在每次连续的测试运行中,所有以前的缺陷修复也会被验证,并且减少了相同缺陷的重复。

  • 由于大部分测试是在开发过程中完成的,因此交付前的测试时间缩短了。

TDD 的缺点

起点是用户故事,描述系统的行为。因此,开发人员经常面临以下问题:

  • 何时测试?

  • 测试什么?

  • 如何知道是否满足规范?

  • 代码是否交付业务价值?

关于 TDD 的误解

行业中存在以下误解,需要澄清。

误解 澄清
TDD 完全关乎测试和测试自动化。 TDD 是一种使用首要测试方法的开发方法。
TDD 不涉及任何设计。 TDD 包括基于需求的关键分析和设计。设计在开发过程中出现。
TDD 仅限于单元级别。 TDD 可用于集成和系统级别。
传统的测试项目无法使用 TDD。 TDD 随着极限编程而流行起来,并且正在其他敏捷方法中使用。但是,它也可以用于传统的测试项目。
TDD 是一种工具。

TDD 是一种开发方法,每次新的单元测试通过后,都会将其添加到自动化测试套件中,因为每当添加新代码或修改现有代码以及每次重构后,都需要运行所有测试。

因此,支持 TDD 的测试自动化工具有助于此过程。

TDD 意味着将验收测试交给开发人员。 TDD 并不意味着将验收测试交给开发人员。

验收 TDD

验收测试驱动开发 (ATDD) 在开发早期创建用户故事时定义验收标准和验收测试。ATDD 重点关注客户、开发人员和测试人员之间的沟通和共同理解。

ATDD 的关键实践如下:

  • 讨论现实场景以建立对领域的共同理解。

  • 使用这些场景来确定验收标准。

  • 自动化验收测试。

  • 将开发重点放在这些测试上。

  • 使用测试作为实时规范以促进更改。

使用 ATDD 的好处如下:

  • 需求明确且没有功能差距。

  • 其他人了解开发人员预见的特殊情况。

  • 验收测试指导开发。

Acceptance TDD

TDD 与 BDD

根据 Dan North 的说法,程序员在执行测试驱动开发时通常会遇到以下问题:

  • 从哪里开始

  • 测试什么和不测试什么

  • 一次测试多少

  • 如何称呼他们的测试

  • 如何理解测试失败的原因

所有这些问题的解决方案都是行为驱动开发。它已从既定的敏捷实践中发展而来,旨在使它们更容易为不熟悉敏捷软件交付的团队所访问和使用。随着时间的推移,BDD 已发展到涵盖敏捷分析和自动化验收测试的更广泛范围。

TDD 和 BDD 之间的区别在于:

  • TDD 描述了软件的工作方式。

  • 另一方面,BDD:

    • 描述最终用户如何使用软件。

    • 促进协作和沟通。

    • 强调系统行为的示例。

    • 旨在从示例中得出可执行的规范

广告