行为驱动开发
行为驱动开发(Behaviour-Driven-Development)简写BDD
BDD是TDD的一种演化,作为一种设计方法,可以有效的改善设计,并在系统演化过程中未团队知名前进方向
行为驱动开发的根基是一种“通用语言”。这种通用语言同时被客户和开发者用来定义系统的行为。由于客户
和开发者使用同一种语言来描述同一个系统, 可以最大程度避免表达不一致带来的问题。
书写格式:
Story:标题(秒速故事的单行文字)
As a 角色
I want 特征
So that 利益
(用一系列的场景来定义验证标准)
Scenario 1 :标题(秒速场景的单行文字)
Give [上下文】
And [更多上下文】
When [事件】
Then [结果】
清单 2. 用于探索行为的一个简单的栈定义
值调用 push(),那么栈应该 抛出一个异常。现在看看我在清单 3 中如何定义这个行为。
清单 3. 如果推出一个 null 值,则栈应该抛出一个异常
在清单 3 中发生的一些事情是 JBhave 特有的,所以要解释一下。首先,我创建 Stack 类的一个实例,并将它限制为 String 类型(通过 Java 5 泛型)。接下来,我使用 JBehave 的 异常框架 实际建模我所期望的行为。 Ensure 类类似于 JUnit 或 TestNG 的 Assert 类型;但是,它增加了一系列方法,提供了更具可读性的 API(这常被称作文学编程)。在清单 3 中,我确保了如果对 null 调用 push(),则抛出一个RuntimeException。
JBehave 还引入了一个 Block 类型,它是通过用所需的行为覆盖 run() 方法来实现的。在内部,JBehave 确保期望的异常类型不被抛出(并因此被捕捉),而是生成一个故障状态。您可能还记得,在我前面关于 用 Google Web Toolkit 对 Ajax 进行单元测试 的文章中,也出现了类似的覆盖便利类的模式。在那种情况下,覆盖是通过 GWT 的 Timer 类实现的。
如果现在运行清单 3 中的行为,应该看到出现错误。按照目前编写的代码,push() 方法不执行任何操作。所以不可能生成异常,从清单 4 中的输出可以看到这一点。
清单 4. 没有发生期望的行为
行为驱动开发(Behaviour-Driven-Development)简写BDD
BDD是TDD的一种演化,作为一种设计方法,可以有效的改善设计,并在系统演化过程中未团队知名前进方向
行为驱动开发的根基是一种“通用语言”。这种通用语言同时被客户和开发者用来定义系统的行为。由于客户
和开发者使用同一种语言来描述同一个系统, 可以最大程度避免表达不一致带来的问题。
书写格式:
Story:标题(秒速故事的单行文字)
As a 角色
I want 特征
So that 利益
(用一系列的场景来定义验证标准)
Scenario 1 :标题(秒速场景的单行文字)
Give [上下文】
And [更多上下文】
When [事件】
Then [结果】
And [其他结果】
JBehave
JBehave是用于java平台的一个BDD框架,源于xUnit范例,JBehave强调“应该”这个词,而不是测试,和JUnit一样,
你可以在自己喜欢的IDE中,或者偏爱的构建平台(例如Ant)运行JBehave类
JBehave允许以JUnit的方式创建行为类,但是,在JBehave中,不需要扩展任何特定的基类,并且所有行为方法都需
要以should而不是test开发
清单 1.用于栈的一个简单行为类
public class StackBehavior {
public void shouldThrowExceptionUponNullPush() throws Exception{}
public void shouldThrowExceptionUponPopWithoutPush() throws Exception{}
public void shouldPopPushedValue() throws Exception{}
public void shouldPopSecondPushedValueFirst() throws Exception{}
public void shouldLeaveValueOnStackAfterPeep() throws Exception{}
}
清单 1中定义的方法都是以should开头,他们都创建一个类可读的句子,这里产生的StackBehavior类描述栈的特征。
清单 2. 用于探索行为的一个简单的栈定义
public class Stack<E> {
public void push(E value) {}
}
可以看到,我编写了一个最简单的栈,以便首先 添加必需的行为。正如 Linda 所说,行为很简单:如果有人对 null
值调用 push(),那么栈应该 抛出一个异常。现在看看我在清单 3 中如何定义这个行为。
清单 3. 如果推出一个 null 值,则栈应该抛出一个异常
public void shouldThrowExceptionUponNullPush() throws Exception{
final Stack<String> stStack = new Stack<String>();
Ensure.throwsException(RuntimeException.class, new Block(){
public void run() throws Exception {
stStack.push(null);
}
});
}
杰出的 expectation 和 override
在清单 3 中发生的一些事情是 JBhave 特有的,所以要解释一下。首先,我创建 Stack 类的一个实例,并将它限制为 String 类型(通过 Java 5 泛型)。接下来,我使用 JBehave 的 异常框架 实际建模我所期望的行为。 Ensure 类类似于 JUnit 或 TestNG 的 Assert 类型;但是,它增加了一系列方法,提供了更具可读性的 API(这常被称作文学编程)。在清单 3 中,我确保了如果对 null 调用 push(),则抛出一个RuntimeException。
JBehave 还引入了一个 Block 类型,它是通过用所需的行为覆盖 run() 方法来实现的。在内部,JBehave 确保期望的异常类型不被抛出(并因此被捕捉),而是生成一个故障状态。您可能还记得,在我前面关于 用 Google Web Toolkit 对 Ajax 进行单元测试 的文章中,也出现了类似的覆盖便利类的模式。在那种情况下,覆盖是通过 GWT 的 Timer 类实现的。
如果现在运行清单 3 中的行为,应该看到出现错误。按照目前编写的代码,push() 方法不执行任何操作。所以不可能生成异常,从清单 4 中的输出可以看到这一点。
清单 4. 没有发生期望的行为