行为驱动
今年我很幸运地在可爱的堪萨斯城参加了KCDC会议。 我参加的会议之一是“ 行为驱动开发” 。 我之前参加过几次BDD会议,并且很喜欢其中的每一个,但是有一个明确的问题使这个问题与众不同。 在了解了在实践中使用BDD的所有好处并兴奋地开始如此出色的发现后,如果您没有任何框架或管理层支持您的任务会怎样?
正如BDD会议所指出的那样,诸如Cucumber和JBehave之类的框架为敏捷团队提供了一种以纯文本格式创建测试场景的方法。 那么,您如何独自提出呢?在个人发展水平上可以实现哪些BDD原则?
由于BDD是测试驱动开发的扩展,因此很容易在单元测试级别使用BDD的原理和关键字。 将BDD降至此级别首先要遵循Dan North建议的单元测试方法名称的命名模板 。
在某些时候,我们都使用了Eclipse中的测试类生成器来节省时间。 它确实为您提供了一个预填充的类,该类在所有可见的方法名称之前添加了单词test,但是从长远来看,这是否节省时间或有所帮助? 容易区分testCalculateCost()用于什么测试吗? 您最终将为该特定方法添加更多测试用例。 您将如何区分每个其他测试用例的方法名称?
Dan North建议使用基于行为的句子来描述测试。 测试方法testCalculateCost()将变为testShouldFailForMissingBillingDate() 。 Dan还建议在描述接下来要测试的内容时,使用“行为”一词来代替臭名昭著的关键字“测试”。 确定calculateCost()的行为并将下一个行为与现有行为进行比较以消除差距是更自然的。 下一个要测试的自然行为可能是testShouldFailForMissingBillingDueDate()缺少到期日期的行为。
在使用Dan Dan建议的命名约定的同时,该课程还演示了如何组织行为测试类以模仿BDD测试场景。 与为JBehave解析而编写的BDD场景一样, 给定/何时/然后 BDD关键字用于帮助构造和组织测试类中所需的内容。 这些BDD关键字替换了普通单元测试中常用的ranging / act / assert关键字。
单位到BDD测试关键字翻译:
单元测试关键字→BDD关键字
安排/组装→给定
行动→何时 断言→然后
虽然不在敏捷团队中的开发人员仍然可以使用这种风格编写行为测试,但是如果不以用户故事作为起点,则可能会增加学习难度。 与要求的项目符号列表相比,翻译包含与完成的个人BDD测试相同结构的用户故事要容易得多。 我们将使用一个非常基本的用户案例以及一些BDD测试方案,以显示用户案例,BDD测试用例和个人BDD测试类的相似程度。
例
我们正在研究一个用户故事,以为Sudoku游戏添加功能,以允许用户验证在进行中的游戏期间选择的数字是否正确。 按照BDD惯例,游戏功能尚未实现。
故事: 验证板。
为了验证所选择的号码
作为一名玩家
我希望游戏验证我选择的号码。
BDD框架将接受以下内容:
方案1:
想知道数字是否错误的玩家
给定正在进行游戏的玩家
当板子上有所有正确的数字时 玩家验证棋盘 然后应将板退回并确认正确
方案2:
想知道数字是否错误的玩家
给定正在进行游戏的玩家
董事会上所有正确的数字 玩家选错号码时 然后应将板退回并验证为不正确 并且不正确的数字将被标记为不正确
由于我们退出了会议,回到了无BDD的世界,我们将不得不使用自己的创造力过程来填补我们个人BDD测试班的胆量。 首先,在学会了这种思维方式之前,采用行为方法进行测试而不根据测试夹具的方法名称进行测试会更加困难和耗时。 过渡到TDD世界并非易事,但这至少是一个进化的步骤。
这样,我们就可以开始构建新的个人BDD测试类,以使用JUnit 4测试verify方法的行为。
按照Dan North的建议,我们可以使用名称SudokuBoardServiceSolveBehavior作为我们的测试类。
public class SudokuBoardServiceVerifyBehavior {
...
}
当我们使用个人BDD填写测试类时,我们将使用以下结构和关键字
给出/何时/然后类似于场景1和2。虽然我们没有场景,但它们确实有助于概念化测试类的结构和组织。
给定的关键字将用于测试夹具的生成方法。 方法名称将有助于定义测试装置和验收测试的范围。 给定的方法将使用JUnit的@Before注释进行注释,并将在共享数据中。 在我们的场景中,我们想从一个填充有正确数字的木板开始。
public class SudokuBoardServiceVerifyBehavior {
@Before
public void givenCorrectBoardNumbers() throws Exception {
//stub the board
board = TestBoardFactory.createPartialBoardWithCorrectNumberes();
//setup the service
service = new SudokuBoardService();
}
}
接下来, when方法包含执行测试夹具的可执行步骤。 根据要测试的不同行为的数量,单个给定方法可能具有多个when方法。 每个时候都可以涵盖BDD测试场景。 when方法将使用JUnit的@Test进行注释。
public class SudokuBoardServiceVerifyBehavior {
….
@Test
public void whenUserPicksCorrectNumber() {
//pick correct number
board.setNumber(POS_X,POS_Y,5);
}
@Test
public void whenUserSelectsInCorrectNumber() {
//pick incorrect number
board.setNumber(POS_X,POS_Y,4);
}
}
现在,我们正在测试夹具上执行行为。 最后一步是找出发生了什么。 我们是否按预期执行了要求? 我们将很快找到then方法。 越是复杂的系统,更多的thens你将不得不因为会有更多的断言作出有关行为。 为了清楚和描述清楚,您到那时将有一个断言。 当发现单元测试失败时,您将立即知道并理解测试失败的原因。 方法名称将描述我们要声明的内容。 负责传递控制它们各自然后结果的方法时,会的人。
public class SudokuBoardServiceVerifyBehavior {
private SudokuBoard board = null;
private SudokuBoardService service = null;
private static int POS_X = 0;
private static int POS_Y = 0;
@Before
public void givenCorrectBoardAndCorrectNumbers() throws Exception {
//stub the board
board = TestBoardFactory.createPartialBoard();
//setup the service
service = new SudokuBoardService();
}
@Test
public void whenUserSelectsCorrectNumber() {
//pick correct number
board.setNumber(POS_X,POS_Y,5);
thenTheBoardIsVerifiedAsCorrect();
}
@Test
public void whenUserSelectsInCorrectNumber() {
//pick incorrect number
board.setNumber(POS_X,POS_Y,4);
thenTheBoardIsVerifiedAsInCorrect();
theTheIncorrectNumberIsFlaggedAsIncorrect();
}
private void thenTheBoardIsVerifiedAsCorrect() {
service.verify(board);
assertTrue(board.isCorrect());
}
private void thenTheBoardIsVerifiedAsInCorrect() {
service.verify(board);
assertFalse(board.isCorrect());
}
private void thenTheIncorrectNumberIsFlaggedAsIncorrect() {
assertTrue(board.getNumber(POS_X,POS_Y).isCorrect());
}
}
那么,为了使BDD达到个人水平而在这里发生了什么?
您刚刚成为框架的替代者。 您只是将一组业务需求转换为单元测试。 唯一的区别是您使用了JUnit批注,而不是Cucumber或JBehave的批注集。 尽管这些行为测试无法与完整的BDD基础架构所提供的价值相提并论,但我们还是能够将BDD原理和结构引入个人水平。 个人BDD仍然提供使用BDD原理专注于直接有助于业务成果的行为的好处。 个人BDD将帮助编写单元测试,以向开发人员提供可通信的证据,证明系统的行为方面正在起作用。 使用更好的测试类和方法命名约定,测试将变得更具描述性。
为了与BDD原则保持一致,测试仍然可以很好地自动化。 一旦所有测试通过,将有一个由功能测试保护的完全实现的业务功能。
翻译自: https://www.javacodegeeks.com/2013/08/personal-behavior-driven-development.html
行为驱动