BDD - BDD 方式的 TDD
在 TDD 中,术语"验收测试"具有误导性。 验收测试实际上代表了系统的预期行为。 在敏捷实践中,强调整个团队的协作以及与客户和其他利益相关者的互动。 这就需要使用项目中每个人都容易理解的术语。
TDD 让您思考所需的行为,因此术语"行为"比术语"测试"更有用。 BDD 是测试驱动开发,其词汇重点关注行为而不是测试。
用 Dan North 的话来说,"我发现从测试思维到行为思维的转变是如此深刻,以至于我开始将 TDD 称为 BDD,即行为驱动开发。" TDD 专注于某些东西将如何工作,BDD 专注于我们构建它的原因。
BDD 回答了开发人员经常面临的以下问题 −
问题 | 答案 |
---|---|
从哪里开始? | 由外而内 |
要测试什么? | 用户案例 |
什么不应该测试? | 还有什么 |
这些答案产生了如下的案例框架−
案例框架
As a [Role]
I want [Feature]
so that [Benefit]
这意味着,"当执行功能时,扮演角色的人将获得好处。"
BDD进一步回答了以下问题 −
问题 | 答案 |
---|---|
一次性测试多少? | 很少关注 |
如何称呼他们的测试? | 句子模板 |
如何理解测试失败的原因 | 文档 |
这些答案导致示例框架如下 −
示例框架
Given(给出)一些初始上下文,
When(当)事件发生时,
Then(然后)确保一些结果。
这意味着,"从初始上下文开始,当特定事件发生时,我们知道结果应该是什么。"
因此,该示例显示了系统的预期行为。 示例用于说明系统的不同场景。
案例和场景
让我们考虑以下由 Dan North 绘制的有关 ATM 系统的插图。
案例
As a(作为)客户,
I want(我想)从 ATM 机提取现金,
so that(这样)我就不用在银行排队了。
场景
这个案例有两种可能的场景。
场景 1 − 账户已入账
Given(鉴于)该帐户有信用
And(并且)该卡有效
And(并且)提款机里有现金
When(当)客户要求现金
Then(然后)确保帐户已记入借方
And(并且)确保发放现金
And(并且)确保卡被退回
场景 2 − 账户透支超过透支限额
Given(鉴于)账户已透支
And(并且)该卡有效
When(当)客户要求现金
Then(然后)确保显示拒绝消息
And(并且)确保不分发现金
And(并且)确保卡被退回
两种场景中的事件相同,但上下文不同。 因此,结果是不同的。
开发周期
BDD 的开发周期是一种由外向内的方法。
步骤 1 − 编写一个变红的高级(外部)业务价值示例(使用 Cucumber 或 RSpec/Capybara)。 (RSpec 用 Ruby 语言生成 BDD 框架)
步骤 2 − 为实现的第一步编写一个较低级别(内部)RSpec 示例,该示例将变为红色。
步骤 3 − 实现最少的代码来通过该较低级别的示例,看看它变绿了。
步骤 4 − 编写下一个较低级别的 RSpec 示例,推动通过变为红色的步骤 1。
步骤 5 − 重复步骤 3 和 4,直到步骤 1 中的高级示例变为绿色。
注意 − 应牢记以下几点 −
红/绿状态是权限状态。
当您的低级测试通过时,您有权编写新示例或重构现有实现。 您不得在重构的情况下添加新的功能/灵活性。
当您的低级测试为红色时,您有权编写或更改实现代码,仅用于使现有测试变为绿色。 您必须抵制编写代码以通过下一个测试(该测试并不存在)的冲动,或者实现您可能认为好的功能(客户不会问)。