BDD - 以BDD的方式进行TDD



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

TDD 让你思考所需的行为,因此“行为”一词比“测试”一词更有用。BDD是测试驱动开发,其词汇重点关注行为而非测试。

用Dan North的话来说,“我发现从以测试为中心思考转向以行为为中心思考的转变如此深刻,以至于我开始将TDD称为BDD,或行为驱动开发。” TDD侧重于事物如何运作,而BDD侧重于我们为什么要构建它。

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

问题 答案
从哪里开始? 从外到内
测试什么? 用户故事
不测试什么? 其他任何东西

这些答案导致以下故事框架:

故事框架

作为[角色]

我想要[功能]

以便[利益]

这意味着,“当功能被执行时,产生的利益归属于扮演角色的人。”

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

问题 答案
每次测试多少? 非常少 - 集中
如何称呼他们的测试? 句子模板
如何理解测试失败的原因? 文档

这些答案导致以下示例框架:

示例框架

给定一些初始上下文,

事件发生时,

确保一些结果。

这意味着,“从初始上下文开始,当某个特定事件发生时,我们知道结果应该是什么。”

因此,示例展示了系统的预期行为。这些示例用于说明系统的不同场景。

故事和场景

让我们考虑Dan North关于ATM系统的以下示例。

故事

作为客户,

我想要从ATM机上取款,

以便我不必在银行排队。

场景

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

场景1 - 账户有余额

给定账户有余额

并且卡片有效

并且出纳机中有现金

客户请求现金时

确保账户被扣款

并且确保现金被发放

并且确保卡片被退回

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

给定账户透支

并且卡片有效

客户请求现金时

确保显示拒绝消息

并且确保现金未被发放

并且确保卡片被退回

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

开发周期

BDD的开发周期采用从外到内的方法。

步骤1 - 编写一个高层次(外部)业务价值示例(使用Cucumber或RSpec/Capybara),使其变为红色。(RSpec在Ruby语言中生成一个BDD框架)

步骤2 - 为第一步实现编写一个较低层次(内部)RSpec示例,使其变为红色。

步骤3 - 实现通过该较低层次示例的最小代码,使其变为绿色。

步骤4 - 编写下一个较低层次的RSpec示例,朝着通过步骤1的方向推进,使其变为红色。

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

注意 - 应牢记以下几点:

  • 红/绿状态是权限状态。

  • 当您的低级测试为绿色时,您有权编写新示例或重构现有实现。在重构的上下文中,您不得添加新功能/灵活性。

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

广告