Behave驱动开发 - 快速指南


Behave驱动开发 - 简介

Behave驱动开发(BDD)是一种最初源于测试驱动开发(TDD)的软件开发过程。

负责 BDD 发展的 Dan North 表示,“BDD 正在使用多个级别的示例来创建共同的理解并消除不确定性,以交付重要的软件。”

BDD 使用示例来说明系统的Behave,这些示例以参与开发的每个人都可读且易于理解的语言编写。这些例子包括 -

  • 转换成可执行的规范。

  • 用作验收测试。

BDD——主要特点

Behave驱动开发的重点是 -

  • 提供共享流程和共享工具,促进软件开发人员、业务分析师和利益相关者之间的沟通,以便在软件开发方面进行协作,以交付具有商业价值的产品。

  • 一个系统应该做什么而不是如何实施。

  • 提供更好的可读性和可见性。

  • 不仅验证软件的运行情况,还验证它是否满足客户的期望。

BDD的起源

如果没有在正确的时间检测到缺陷并在检测到缺陷时进行修复,则修复缺陷的成本会成倍增加。考虑以下示例。

BDD的起源

这表明,除非正确获得需求,否则在后期修复因误解需求而导致的缺陷将是昂贵的。此外,最终产品可能无法满足客户的期望。

当前需要的是一种开发方法 -

  • 是根据要求来的。

  • 在整个开发过程中关注需求。

  • 确保满足要求。

能够满足上述需求的一种开发方法就是BDD。因此,Behave驱动的发展 -

  • 得出系统不同预期Behave的示例。

  • 允许使用业务领域术语以语言编写示例,以确保参与开发的每个人(包括客户)都能轻松理解。

  • 通过对话的方式不时获得客户认可的示例。

  • 在整个开发过程中关注客户需求(示例)。

  • 使用示例作为验收测试。

BDD实践

BDD 的两个主要实践是 -

  • 示例规范 (SbE)

  • 测试驱动开发 (TDD)

举例说明

示例规范 (SbE) 使用对话中的示例来说明业务规则和要构建的软件的Behave。

示例需求说明使产品所有者、业务分析师、测试人员和开发人员能够消除对业务需求的常见误解。

测试驱动开发

在 BDD 背景下,测试驱动开发将示例转化为人类可读、可执行的规范。

开发人员使用这些规范作为实现新功能增量的指南。这样就形成了精简的代码库和一套自动回归测试,可以在软件的整个生命周期中保持较低的维护成本。

敏捷BDD

在敏捷软件开发中,BDD方法用于对待定规范达成共识。

在敏捷 BDD 中执行以下步骤 -

  • 开发人员和产品所有者在纯文本编辑器中协作编写待定规范。

  • 产品所有者指定他们期望系统的Behave。

  • 开发商

    • 用这些Behave细节填写规范。

    • 根据他们对系统的理解提出问题。

  • 考虑当前的系统Behave,看看新功能是否会破坏任何现有功能。

敏捷宣言和 BDD

敏捷宣言指出以下内容 -

我们通过实践并帮助他人开发软件,从而发现更好的软件开发方法。通过这项工作,我们认识到了价值 -

  • 个人和互动- 优于流程和工具

  • 工作软件- 综合文档

  • 客户协作- 胜过合同谈判

  • 响应变化——而不是遵循计划

也就是说,虽然右侧的项目有价值,但我们更看重左侧的项目。

BDD 与敏捷宣言保持一致,如下所示:

敏捷宣言 BDD对齐
个人以及流程和工具上的交互。 BDD 是关于对话。
工作软件胜过全面的文档。 BDD 专注于让创建具有商业价值的软件变得容易。
客户协作胜过合同谈判。 BDD专注于基于想法的场景,随着开发的进展不断与客户沟通。它不是基于任何承诺。
响应变化而不是遵循计划。 BDD 注重持续的沟通和协作,以促进吸收变化。

BDD-测试驱动开发

当您查看有关Behave驱动开发的任何参考资料时,您会发现诸如“BDD 源自 TDD”、“BDD 和 TDD”之类的短语的用法。要知道BDD是怎么产生的,为什么说它是从TDD衍生出来的,什么是BDD、TDD,就得对TDD有一定的了解。

为什么要测试?

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

测试

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

探索性测试

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

最后测试方法面临的挑战

在软件开发项目中相当长一段时间都遵循最后测试方法。然而,实际上,使用这种方法,由于测试必须等到特定阶段完成,因此经常被忽视,因为 -

  • 阶段完成的延迟。

  • 时间安排紧张。

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

此外,在“最后测试”方法中,通常会跳过本应由开发人员完成的单元测试。发现的各种原因基于开发人员的心态 -

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

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

  • 他们的编码效率很高,而且他们的代码不会有缺陷。

这导致 -

  • 损害所交付产品的质量。

  • 仅由测试人员对质量负责。

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

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

这些因素要求转变范式,将重点放在测试上。结果是测试优先的方法。

测试优先方法

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

这种方法被纳入以下软件开发方法(也是敏捷的) -

  • 极限编程( XP )_

  • 测试驱动开发(TDD

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

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

红-绿-重构循环

测试驱动开发用于开发由单元测试引导的代码。

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

第 2 步- 编写测试

步骤 3 - 运行测试。

测试失败,因为代码还没有写。因此,步骤 2 通常称为编写失败测试。

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

步骤 5 - 运行所有测试以确保它们全部通过。单元测试是自动化的以促进此步骤。

步骤 6 - 重构。

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

每个周期应该很短,典型的一个小时应该包含许多周期。

红绿重构周期

这也被普遍称为红-绿-重构循环,其中 -

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

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

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

TDD 流程步骤

TDD 过程的步骤如下所示。

TDD 流程步骤

TDD 的优点

测试驱动开发的好处或优点是 -

  • 开发人员在创建代码之前需要首先了解所需的结果应该是什么以及如何测试它。

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

  • 由于单元测试套件在每次重构后运行,因此每个组件仍在工作的反馈是恒定的。

  • 单元测试充当始终符合数据的动态文档。

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

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

  • 开发人员有信心进行任何更改,因为如果更改影响任何现有功能,则通过运行测试会发现相同的情况,并且可以立即修复缺陷。

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

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

TDD 的缺点

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

  • 什么时候测试?

  • 要测试什么?

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

  • 代码能否带来商业价值?

关于 TDD 的误解

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

误解 澄清
TDD 是关于测试和测试自动化的。 TDD 是一种使用测试优先方法的开发方法。
TDD不涉及任何设计。 TDD 包括基于需求的关键分析和设计。设计是在开发过程中出现的。
TDD 仅在单元级别。 TDD 可以在集成和系统级别使用。
TDD 不能用于传统的测试项目。 TDD 在极限编程中变得流行,并被用于其他敏捷方法中。然而,它也可以用于传统的测试项目。
TDD 是一种工具。

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

因此,支持 TDD 的测试自动化工具促进了这一过程。

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

验收TDD

验收测试驱动开发 (ATDD) 在开发早期的用户故事创建过程中定义了验收标准和验收测试。ATDD注重客户、开发人员和测试人员之间的沟通和共识。

ATDD 的关键实践如下:

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

  • 使用这些场景来达到验收标准。

  • 自动化验收测试。

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

  • 使用测试作为实时规范来促进变更。

使用 ATDD 的好处如下:

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

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

  • 验收测试指导开发。

验收TDD

TDD 与 BDD

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

  • 从哪儿开始

  • 测试什么和不测试什么

  • 一次性测试多少

  • 他们的测试该如何称呼

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

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

TDD 和 BDD 之间的主要区别是 -

  • TDD 描述了软件的工作原理。

  • 另一方面,BDD -

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

    • 促进协作和沟通。

    • 强调系统Behave的示例。

    • 针对从示例中导出的可执行规范

BDD - BDD 方式的 TDD

在 TDD 中,术语“验收测试”具有误导性。验收测试实际上代表了系统的预期Behave。在敏捷实践中,强调整个团队的协作以及与客户和其他利益相关者的互动。这就产生了使用项目中每个人都容易理解的术语的必要性。

TDD 让您思考所需的Behave,因此术语“Behave”比术语“测试”更有用。BDD 是测试驱动开发,其词汇重点关注Behave而不是测试。

用 Dan North 的话说,“我发现从测试思维到Behave思维的转变是如此深刻,以至于我开始将 TDD 称为 BDD,即Behave驱动开发。” TDD 专注于某些东西如何工作,BDD 专注于我们构建它的原因。

BDD 回答了开发人员经常面临的以下问题 -

问题 回答
从哪儿开始? 由外向内
要测试什么? 用户故事
什么不应该测试? 还要别的吗

这些答案导致故事框架如下 -

故事框架

作为[角色]

我想要[功能]

这样[好处]

这意味着,“当执行某项功能时,所产生的好处是扮演该角色的人。” '

BDD 进一步回答了以下问题 -

问题 回答
一次性测试多少? 非常不专心
他们的测试该怎么称呼? 句子模板
如何理解测试失败的原因 文档

这些答案导致示例框架如下 -

示例框架

给定一些初始背景,

事件发生时,

然后确保一些结果。

这意味着,“从最初的背景开始,当特定事件发生时,我们知道结果应该是什么。”

因此,该示例显示了系统的预期Behave。这些示例用于说明系统的不同场景。

故事和场景

让我们考虑以下由 Dan North 绘制的有关 ATM 系统的插图。

故事

作为客户,

我想从 ATM 机提取现金,

这样我就不用去银行排队了。

应用场景

这个故事有两种可能的场景。

场景 1 - 账户有信用

鉴于该帐户是贷方

并且卡有效

分配器里装有现金

顾客要求现金时

然后确保账户已被扣款

确保分发现金

确保卡被退回

场景 2 - 账户透支超过透支限额

鉴于账户已透支

并且卡有效

顾客要求现金时

然后确保显示拒绝消息

确保不分发现金

确保卡被退回

两个场景中的事件相同,但上下文不同。因此,结果是不同的。

开发周期

BDD 的开发周期是一种由外而内的方法。

步骤 1 - 编写一个变红的高级(外部)业务价值示例(使用 Cucumber 或 RSpec/Capybara)。(RSpec 用 Ruby 语言生成 BDD 框架)

步骤 2 - 为实现的第一步编写一个较低级别(内部)RSpec 示例,该示例变为红色。

步骤 3 - 实现最低代码以通过该较低级别的示例,看到它变绿。

步骤 4 - 编写下一个较低级别的 RSpec 示例,推动通过步骤 1(变为红色)。

步骤 5 - 重复步骤步骤 3 和步骤 4,直到步骤 1 中的高级示例变为绿色。

注意- 应牢记以下几点 -

  • 红/绿状态是许可状态。

  • 当您的低级测试通过时,您有权编写新示例或重构现有实现。您不得在重构的情况下添加新的功能/灵活性。

  • 当您的低级测试为红色时,您有权编写或更改实现代码,仅用于使现有测试变为绿色。您必须抵制编写代码以通过下一个测试(该测试并不存在)的冲动,或者实现您可能认为好的功能(客户不会问)。

BDD - 规范示例

根据《实例化需求说明》一书的作者 Gojko Adzic 的说法,实例化需求说明是一组过程模式,可以促进软件产品的变更,以确保高效地交付正确的产品。

示例需求说明是一种协作方法,用于定义软件产品的需求和面向业务的功能测试,其基础是使用实际示例而不是抽象语句来捕获和说明需求。

示例规范 – 概述

示例需求说明的目标是专注于开发和交付优先化的、可验证的业务需求。虽然示例需求说明的概念本身相对较新,但它只是对现有实践的重新表述。

它支持一种非常具体、简洁的词汇,称为无处不在的语言 -

  • 启用可执行的要求。

  • 被团队中的每个人使用。

  • 由跨职能团队创建。

  • 得到了大家的理解。

示例规范可以用作构建反映业务领域的自动化测试的直接输入。因此,实例化需求说明的重点是构建正确的产品并构建正确的产品。

举例说明的目的

实例化需求说明的主要目的是构建正确的产品。它注重共同理解,从而建立单一的事实来源。它可以实现验收标准的自动化,以便重点关注缺陷预防而不是缺陷检测。它还提倡尽早测试,尽早发现缺陷。

锑化硼的用途

示例规范用于说明描述业务价值的预期系统Behave。说明是通过具体和现实生活中的例子来进行的。这些示例用于创建可执行要求:

  • 无需翻译即可测试。

  • 在实时文档中捕获。

以下是我们使用示例来描述特定规格的原因 -

  • 它们更容易理解。

  • 它们更难被误解。

SbE的优点

使用实例说明的优点是 -

  • 提高质量

  • 减少浪费

  • 降低生产缺陷的风险

  • 集中精力

  • 可以更安全地进行更改

  • 提高业务参与度

SbE的应用

示例规范在以下领域找到应用:

  • 要么是复杂的业务,要么是复杂的组织。

  • 对于纯粹的技术问题效果不佳。

  • 不适用于以 UI 为中心的软件产品。

  • 也可以应用于遗留系统。

SbE 和验收测试

示例规范在验收测试方面的优点是 -

  • 一张插图用于详细需求和测试

  • 该项目的进展是在验收测试方面 -

    • 每个测试都是为了测试一种Behave。

    • 测试要么通过某种Behave,要么不通过。

    • 通过测试表示特定Behave已完成。

    • 如果一个需要完成 100 个Behave的项目完成了 60 个Behave,那么它就完成了 60%。

  • 测试人员从缺陷修复转向缺陷预防,他们为解决方案的设计做出了贡献。

  • 自动化可以立即了解需求变更对解决方案的影响。

示例规范 – 对于不同角色意味着什么

示例需求说明的目标是促进团队中每个人(包括整个项目中的客户)的协作,以交付业务价值。为了更好地理解,每个人都使用相同的词汇。

角色 锑化硼的用途
业务分析师
  • 要求明确且没有功能差距。

  • 开发人员,实际阅读规范。

开发商
  • 开发人员更好地了解正在开发的内容。

  • 通过计算已正确开发的规范,可以更好地跟踪开发进度。

测试员
  • 测试人员更好地了解正在测试的内容。

  • 测试人员从一开始就参与其中并在设计中发挥作用。

  • 测试人员致力于缺陷预防而不是缺陷检测。

每个人
  • 从一开始就识别错误可以节省时间。

  • 优质的产品是从一开始就生产出来的。

SbE – 一组过程模式

正如我们在本章开头所看到的,示例需求说明被定义为一组过程模式,这些模式促进软件产品的变更,以确保有效地交付正确的产品。

流程模式是 -

  • 协作规范

  • 使用示例说明规格

  • 细化规范

  • 自动化示例

  • 经常验证

  • 生活文档

协作规范

协作规范的目标是 -

  • 让团队中的不同角色有共同的理解和共享的词汇。

  • 让每个人都参与到项目中,以便他们可以就某个功能贡献自己的不同观点。

  • 确保共享通信和功能所有权。

这些目标是在规范研讨会(也称为“三个朋友会议”)中实现的。三个朋友是 BA、QA 和开发人员。尽管项目中还有其他角色,但这三个角色将从定义到功能交付负责。

会议期间 -

  • 业务分析师 (BA) 提出新功能的要求和测试。

  • 三位好友(BA、开发人员和 QA)讨论新功能并审查规范。

  • QA 和开发人员还可以识别缺失的需求。

  • 三个朋友

    • 使用通用语言来利用共享模型。

    • 使用领域词汇(如果需要,可以维护词汇表)。

    • 寻找差异和冲突。

  • 此时不要跳转到实现细节。

  • 就某个功能是否已充分指定达成共识。

  • 共同的需求意识和测试所有权有利于质量规范

  • 这些需求以场景的形式呈现,提供了明确、明确的需求。场景是从用户角度来看系统Behave的示例。

使用示例说明规范

使用 Give-When-Then 结构指定场景来创建可测试的规范 -

给定<一些前提>

并且<附加前提条件>可选

<动作/触发发生>时

然后<一些后置条件>

并且<附加后置条件>可选

该规范是系统Behave的示例。它还代表系统的验收标准。

团队讨论这些示例并合并反馈,直到就这些示例涵盖该功能的预期Behave达成一致。这确保了良好的测试覆盖率。

细化规范

为了完善规范,

  • 写例子时要精确。如果一个示例变得复杂,请将其拆分为更简单的示例。

  • 专注于业务角度,避免技术细节。

  • 考虑积极和消极的条件。

  • 遵守特定领域的词汇。

  • 与客户讨论示例。

    • 选择对话来完成此任务。

    • 仅考虑客户感兴趣的那些示例。这样可​​以仅生成所需的代码,并避免覆盖可能不需要的所有可能的组合

  • 为了确保场景通过,该场景的所有测试用例都必须通过。因此,增强规范以使其可测试。测试用例可以包括各种范围和数据值(边界和极端情况)以及导致数据更改的不同业务规则。

  • 指定额外的业务规则,例如复杂计算、数据操作/转换等。

  • 包括非功能性场景(例如性能、负载、可用性等)作为示例规范

自动化示例

自动化层需要保持非常简单——只需将规范连接到被测系统即可。您可以使用工具来实现同样的目的。

使用领域特定语言 (DSL) 执行测试自动化,并显示输入和输出之间的清晰连接。专注于规范,而不是脚本。确保测试精确、易于理解和可测试。

经常验证

在每次更改(添加/修改)时,在开发管道中包含示例验证。可以(并且应该)采用许多技术和工具来帮助确保产品的质量。它们围绕三个关键原则 -尽早测试、良好测试经常测试

经常执行测试,以便识别薄弱环节。代表Behave的示例有助于跟踪进度,只有在相应的测试通过后,Behave才被称为完成。

生活文档

使规格尽可能简单和简短。组织规范并随着工作的进展不断完善它们。使团队中的所有人都可以访问文档。

通过示例流程步骤进行规范

该图显示了示例需求说明中的流程步骤。

生活文档

反模式

反模式是软件开发中的某些模式,被认为是不好的编程实践。设计模式是解决常见问题的常用方法,已被形式化,通常被认为是一种良好的开发实践,而反模式则相反,是不可取的

反模式会引起各种问题。

反模式 问题
没有合作
  • 许多假设

  • 构建错误的东西

  • 测试错误的东西

  • 不知道代码何时完成

不知道代码何时完成
  • 难以维护测试

  • 很难理解规格

  • 业务代表失去兴趣

过于详细或过于以 UI 为中心的示例
  • 难以维护测试

  • 难以理解的规格

  • 业务代表失去兴趣

低估所需的努力
  • 团队认为他们失败了并且很早就感到失望

问题的解决方案——质量

通过监视反模式可以确保质量。为了最大限度地减少反模式造成的问题,您应该 -

  • 聚在一起使用示例来指定。

  • 清理并改进示例。

  • 编写一段代码,满足示例

  • 自动化示例并部署。

  • 对每个用户故事重复该方法。

要解决因反模式引起的问题意味着坚持 -

  • 合作。

  • 专注于什么。

  • 专注于商业。

  • 做好准备。

让我们了解以上每一项的含义。

合作

合作中 -

  • 业务人员、开发人员和测试人员从自己的角度提供意见。

  • 自动化示例证明团队构建了正确的东西。

  • 这个过程比测试本身更有价值。

专注于什么

你必须关注这个问题——“什么”。专注于“什么” -

  • 不要试图涵盖所有可能的情况。

  • 不要忘记使用不同类型的测试。

  • 使示例尽可能简单。

  • 示例应该易于系统用户理解。

  • 工具不应在研讨会中发挥重要作用。

专注于商业

专注于业务 -

  • 保持规范符合业务意图。

  • 让业务参与创建和审查规范。

  • 隐藏自动化层中的所有细节。

做好准备

做好以下准备 -

  • 即使团队做法发生了变化,好处也不会立即显现出来。

  • 引入 SbE 具有挑战性。

  • 需要时间和投资。

  • 自动化测试并不是免费的。

工具

尽管实际上有多种工具可用,但示例需求说明并不强制使用工具。有些案例即使不使用工具也能成功遵循示例需求说明。

以下工具支持示例说明 -

  • Cucumber

  • 规格流

  • 健身

  • Behave举止

  • Concordion

  • 贝哈特

  • 茉莉花

  • 津津有味

  • 光谱记录

Behave驱动开发 - 工具

开发团队经常错误地认为BDD是一个工具框架。实际上,BDD是一种开发方法而不是工具框架。然而,与其他开发方法一样,也有用于 BDD 的工具。

多种 BDD 工具可用于不同的平台和编程语言。他们是 -

  • Cucumber(Ruby 框架)

  • SpecFlow(.NET 框架)

  • Behave(Python 框架)

  • JBehave(Java 框架)

  • JBehave Web(与 Selenium 集成的 Java 框架)

  • Lettuce(Python框架)

  • Concordion(Java 框架)

  • Behat(PHP 框架)

  • Kahlan(PHP 框架)

  • DaSpec(JavaScript 框架)

  • Jasmine(JavaScript 框架)

  • Cucumber-js(JavaScript 框架)

  • Squish GUI Tester(适用于 JavaScript、Python、Perl、Ruby 和 Tcl 的 BDD GUI 测试工具)

  • Spock(Groovy 框架)

  • Yadda(Gherkin 语言支持 Jasmine(JavaScript 框架)等框架)

Cucumber

Cucumber 是全球使用的可执行规范的免费工具。Cucumber 让软件开发团队以纯文本方式描述软件的Behave方式。该文本以业务可读、特定于领域的语言编写,并用作文档、自动化测试和开发辅助,全部汇总为一种格式。您可以通过 Cucumber 使用四十多种不同的口语(英语、中文等)。

Cucumber – 主要特征

Cucumber的主要特点如下 -

  • Cucumber 可用于可执行规范、测试自动化和实时文档。

  • Cucumber 可与用任何语言编写的 Ruby、Java、NET、Flex 或 Web 应用程序配合使用。

  • Cucumber 支持更简洁的表测试 - 类似于 FIT 所做的。

  • Cucumber 通过将需求、自动化测试和文档融合为一个整体:验证软件的纯文本可执行规范,彻底改变了软件开发生命周期。

规格流

SpecFlow 是适用于 .NET 平台的 BDD 工具。SpecFlow 是一个开源项目。源代码托管在 GitHub 上。

SpecFlow 使用 Gherkin 语法来实现功能。Gherkin 格式由 Cucumber 引入,也被其他工具使用。Gherkin 语言作为 GitHub 上的一个项目进行维护 - https://github.com/cucumber/gherkin

表现

Behave 用于 Python 框架。

  • Behave 适用于存储在名为“features”的目录中的三种类型的文件 -

    • 包含您的Behave场景的功能文件。

    • “steps”目录包含场景的 Python 步骤实现。

    • (可选)一些环境控制(在步骤、场景、功能或整个拍摄比赛之前和之后运行的代码)。

  • Behave特征是使用 Gherkin(经过一些修改)编写的,并命名为“name.feature”。

  • 附加到功能和场景的标签可通过传递给它们的“功能”或“场景”对象在环境函数中使用。在这些对象上有一个名为“tags”的属性,它是附加的标签名称列表,按照它们在功能文件中找到的顺序排列。

  • 对小Cucumber标准的修改 -

    • Behave 可以解析标准 Gherkin 文件并扩展 Gherkin 以允许小写步骤关键字,因为这些有时可以允许更具可读性的功能规范

莴苣

Lettuce是一个非常简单的基于Cucumber的BDD工具。它可以执行纯文本功能描述作为 Python 项目的自动化测试。Lettuce 的目标是 BDD 上最常见的任务。

Concordion

Concordion 是一个开源工具,用于自动化 Java 框架示例规范。

虽然核心功能很简单,但强大的扩展框架 API 允许您添加功能,例如使用 Excel 电子表格作为规范、向输出添加屏幕截图、显示日志记录信息等。

Concordion 允许您使用段落、表格和正确的标点符号以正常语言编写规范,而无需使用 Give/When/Then 的结构化语言。

Concordion 已被移植到其他语言,包括 -

  • C# (Concordion.NET)

  • Python(PyConcordion)

  • Ruby(RubyConcordion)

Behave驱动开发 - Cucumber

Cucumber 是一个支持可执行规范、测试自动化和实时文档的工具。

Behave驱动开发扩展了示例规范。它还正式确定了测试驱动开发的最佳实践,特别是从外到内的工作视角。开发工作基于可执行的规范。

可执行规范的主要特征如下 -

  • 可执行的规范是 -

    • 来自代表系统Behave的示例。

    • 由所有参与开发的人员(包括企业和利益相关者)合作编写。

    • 基于验收标准。

  • 基于可执行规范的验收测试是自动化的。

  • 使用一种共享的、普遍存在的语言来编写可执行规范和自动化测试,以便:

    • 在整个开发过程中使用领域特定术语。

    • 每个人,包括客户和利益相关者,都以同样的方式谈论系统、其需求及其实施。

    • 相同的术语用于讨论需求、设计文档、代码、测试等中存在的系统。

    • 任何人都可以阅读和理解需求以及如何生成更多需求。

    • 可以轻松适应变化。

    • 维护实时文档。

Cucumber 有助于此过程,因为它将可执行规范与系统的实际代码和自动验收测试联系在一起。

它这样做的方式实际上是为了让客户和开发人员一起工作。当验收测试通过时,意味着它所代表的系统Behave规范已被正确实现。

典型的Cucumber验收测试

考虑以下示例。

功能 - 注册

  • 注册应该快速且友好。

  • 场景 - 成功注册

    • 用户应该会收到一封确认电子邮件并受到亲自问候。

    • 既然我选择了报名。

    • 我使用有效的详细信息注册时。

    • 然后我应该会收到一封确认电子邮件。

    • 应该会看到一条个性化的问候语。

从这个例子中,我们可以看到 -

  • 验收测试参考功能

  • 功能通过场景进行解释。

  • 场景由步骤组成。

该规范以自然语言编写在纯文本文件中,但它是可执行的。

Cucumber的加工

Cucumber 是一个命令行工具,它处理包含功能的文本文件,寻找可以针对您的系统执行的场景。让我们了解一下 Cucumber 的工作原理。

  • 它使用了一系列有关文件命名方式和文件所在位置(相应文件夹)的约定,以方便入门。

  • Cucumber 允许您将规范、自动化测试和文档保存在同一个地方。

  • 每个场景都是一个步骤列表,描述场景的前置条件、操作和后置条件;如果每个步骤执行时没有任何错误,则该场景被标记为通过。

  • 运行结束时,Cucumber 将报告通过了多少个场景。

  • 如果出现问题,它会提供有关失败原因的信息,以便开发人员可以继续进行。

在 Cucumber 中,FeaturesScenarios和 Steps 是用一种称为Gherkin的语言编写的。

Gherkin 是具有结构的纯文本英语(或 60 多种其他语言之一)。Gherkin 易于学习,其结构允许您以简洁的方式编写示例。

  • Cucumber 执行包含用 Gherkin 编写的可执行规范的文件。

  • Cucumber 需要步骤定义将纯文本 Gherkin 步骤转换为与系统交互的操作。

  • 当 Cucumber 执行场景中的步骤时,它将查找匹配的步骤定义来执行。

  • 步骤定义是一小段带有附加模式的代码。

  • 该模式用于将步骤定义链接到所有匹配的步骤,而代码是 Cucumber 在看到 Gherkin 步骤时将执行的代码。

  • 每个步骤都附有步骤定义。

  • 大多数步骤将收集输入,然后委托给特定于您的应用程序域的框架,以便在您的框架上进行调用。

Cucumber 支持十多个不同的软件平台。您可以选择适合您的 Cucumber 实现。每个 Cucumber 实现都提供相同的整体功能,并且它们还有自己的安装过程和特定于平台的功能。

映射步骤和步骤定义

Cucumber 的关键是步骤和步骤定义之间的映射。

绘图步骤

Cucumber实施

下面给出的是 Cucumber 实现。

框架整合

下面给出了框架的实现。

Behave驱动发展 - 小Cucumber

Gherkin 是一种语言,用于编写功能、场景和步骤。Gherkin 的目的是帮助我们编写具体的需求。

要理解具体要求的含义,请考虑以下示例 -

应防止客户输入无效的信用卡详细信息。

相对

如果客户输入的信用卡号长度不完全是 16 位数字,那么当他们尝试提交表单时,应该会重新显示错误消息,告知他们正确的位数。

后者没有歧义,可以避免错误,并且更易于测试。

Gherkin 旨在创建更具体的要求。在 Gherkin 中,上面的例子看起来像 -

特征

输入无效信用卡详细信息时的反馈特征定义

在用户测试中,我们看到很多人犯错误文档

背景适用于以下所有场景

鉴于我已经选择了要购买的商品,

即将输入我的信用卡号码

场景- 信用卡号太短场景定义

我输入长度小于 16 位的卡号时

所有其他细节都是正确的

提交表格脚步

然后表格应该重新显示

应该会看到一条消息,告知我正确的位数

Gherkin 格式和语法

Gherkin 文件是纯文本文件,扩展名为 .feature。每行非空白都必须以 Gherkin 关键字开头,后跟您喜欢的任何文本。关键词是 -

  • 特征

  • 设想

  • 给定、何时、那么、并且、但是(步骤)

  • 背景

  • 场景概要

  • 例子

  • “””(文档字符串)

  • | (数据表)

  • @(标签)

  • # (评论)

  • *

特征

Feature关键字用于描述软件功能,并对相关场景进行分组功能具有三个基本元素 -

  • 关键词——功能。

  • 功能的名称,与功能关键字在同一行提供。

  • 可选(但强烈推荐)的描述,可以跨越多行,即包含关键字“功能”的行与以“场景”、“背景”或“场景大纲”开头的行之间的所有文本。

除了名称和描述之外,功能还包含场景或场景轮廓的列表以及可选的背景。

通常,通过获取功能名称、将其转换为小写并用下划线替换空格来命名.feature文件。例如,

feedback_when_entering_invalid_credit_card_details.feature

为了识别系统中的功能,您可以使用所谓的“功能注入模板”。

作为<用户类型>,为了<实现某些目标>,我想要<一项功能>

描述

Gherkin 文档的某些部分不必以关键字开头。

在功能、场景、场景大纲或示例后面的行中,您可以编写任何您喜欢的内容,只要没有任何行以关键字开头即可。这是包含描述的方法。

设想

为了表达系统的Behave,您可以为每个功能附加一个或多个场景。通常每个功能会看到 5 到 20 个场景,以完全指定围绕该功能的所有Behave。

场景遵循以下模式 -

  • 描述初始上下文

  • 描述一个事件

  • 描述预期结果

我们从上下文开始,描述操作,然后检查结果。这是通过步骤完成的。Gherkin 提供了三个关键字来描述每个上下文、操作和结果作为步骤。

  • 给定- 建立上下文

  • 何时- 执行操作

  • 然后- 检查结果

这些关键字提供了场景的可读性。

例子

场景- 从帐户中提取资金。

  • 鉴于我的帐户中有 100 美元。

  • 我要求 20 美元时。

  • 那么应该发放 20 美元。

如果有多个彼此相邻的GiveWhen步骤,您可以使用AndBut。它们允许您详细指定场景。

例子

场景- 尝试使用被盗的卡提款。

  • 鉴于我的帐户中有 100 美元。

  • 我的卡无效。

  • 我要求 50 美元时。

  • 那么我的卡就不应该被退回。

  • 我应该被告知联系银行。

创建场景时,请记住“每个场景都必须有意义并且能够独立于任何其他场景执行”。这意味着 -

  • 一个场景的成功条件不能依赖于在它之前执行过的其他场景的事实。

  • 每个场景都会创建其特定的上下文,执行一件事并测试结果。

这种情况提供以下好处 -

  • 测试将变得更简单、更容易理解。

  • 您可以只运行场景的子集,而不必担心测试集的破坏。

  • 根据您的系统,您也许能够并行运行测试,从而减少执行所有测试所需的时间。

场景概要

如果您必须编写具有多个输入或输出的场景,则最终可能会创建多个仅其值不同的场景。解决方案是使用场景大纲。要写出情景大纲,

  • 场景大纲步骤中的变量用 < 和 > 标记。

  • 变量的各种值在表中作为示例给出。

例子

假设您正在编写一个用于在计算器上添加两个数字的功能。

功能- 添加。

Scenario Outline: Add two numbers.
Given the input "<input>"
When the calculator is run
Then the output should be <output>"
Examples
| input    | output |
| 2+2      | 4      | 
| 98+1     | 99     |
| 255+390  | 645    |

场景大纲部分后面始终跟随一个或多个示例部分,这些示例是表格的容器。该表必须具有与场景大纲步骤中的变量相对应的标题行。下面的每一行都会创建一个新场景,填充变量值

Behave驱动开发 - SpecFlow

SpecFlow 是一个开源项目。源代码托管在 GitHub 上。SpecFlow 用于存储应用程序中功能(用例、用户故事)的接受标准的功能文件是使用 Gherkin 语法定义的。

Gherkin 格式由 Cucumber 引入,也被其他工具使用。Gherkin 语言作为 GitHub 上的一个项目进行维护 - https://github.com/cucumber/gherkin

特征元素和 SpecFlow

特征元素的主要特征是 -

  • feature 元素提供功能文件的标头。功能元素包括应用程序中相应功能的名称和高级描述。

    • SpecFlow 为特征元素生成一个单元测试类,类名源自特征的名称。

    • SpecFlow 根据代表验收标准的场景生成可执行单元测试。

  • 功能文件可能包含用于描述功能的验收测试的多个场景。

    • 场景有一个名称,并且可以包含多个场景步骤。

    • SpecFlow 为每个场景生成一个单元测试方法,方法名称源自场景名称。

多场景步骤

场景可以有多个场景步骤。共有三种类型的步骤定义构成验收测试的前提条件、操作或验证步骤。

  • 不同类型的步骤分别以Give、WhenThen关键字开始,相同类型的后续步骤可以使用AndBut关键字链接。

  • Gherkin 语法允许这三种类型的步骤的任意组合,但场景通常具有不同的块