行为驱动开发准备好了吗?

栏目: 编程工具 · 发布时间: 5年前

内容简介:根据BDD in action一书的介绍,Behavior-Driven Development (BDD) is a set of software engineering practices
编辑推荐:

本文来自于csdn,本文主要通过行为驱动开发BDD的例子说明为什么使用行为驱动开发,用什么框架来做行为驱动开发,行为驱动开发的核心原理,希望对您的学习有所帮助。

行为驱动开发准备好了吗?

根据BDD in action一书的介绍,

Behavior-Driven Development (BDD) is a set of software engineering practices

designed to help teams build and deliver more valuable, higher quality software faster.

It draws on Agile and lean practices including, in particular, Test-Driven Development

(TDD) and Domain-Driven Design (DDD). But most importantly, BDD provides a common language based on simple, structured sentences expressed in English (or in the native language of the stakeholders) that facilitate communication between project team members and business stakeholders.

翻译成中文的大概意思就是,行为驱动开发是一个软件工程的系列实践,能够帮助团队快速构建和交付更多价值和质量的软件产品。其和敏捷已经精益的开发实践,是一脉相承的,特别是测试驱动开发,已经领域驱动开发。但是最重要的是BDD提供了一种通用的,简单的,结构化的描述语言,这种语言既可以是英语也可以是其他本地的语言,通过他能够很方便让项目成员和业务干系人非常顺畅的沟通需求,及时这些干系人不懂的任何编程语言。下面就是一个例子。

行为驱动开发准备好了吗?

是不是很好读懂,上面其实就叫Feature(特性文件),其遵循的Gherkin标准,其有下面的关键字,很好理解,

1.Feature

2.Background

3.Scenario

4.Given

5.When

6.Then

7.And

8.But

9.*

10.Scenario Outline

11.Examples

这种特性文件,客户,项目经理,BA,QA都能看懂,因为其就是一个故事点或者需求点,而且通过特定的工具,比如cucumber的工具,能够把其自动转换成为代码。开发人员根据自动生成的代码,断言一些预期的行为,并根据这些行为,完成相应的代码实现,在代码实现的基础上,进行重构; 这样就为一个项目中的各个人员了解项目的需求,实现提供了一个很好的交互桥梁。下面是其一个交互的过程。

行为驱动开发准备好了吗?

如果是传统的方式,其交互方式,应该是,

行为驱动开发准备好了吗?

通过对比,大家是不是发现BDD的这种方式,把用户或者客户真正的通过Feature文件联系在一起了,其沟通是顺畅的,QA,BA,开发,测试,客户,用户可以通过这一媒介,进行高效无障碍的沟通,而不是像传统的方式,通过BA进行二次转达,从而丢失了很多重要的需求。

由此可见,其BDD的好处如下:

减少浪费

节省成本

容易并且安全的适应变化

因为少了中间的转达环节,从而能够快速交付产品

下面看一个简单的例子

行为驱动开发准备好了吗?

从上图可以看出,当一个需求过来的时候,先通过项目干系人都能理解的Feature文件,描述项目的User Story, 有的里面还有详细生动的数据范例(example),从而能够让所有的人更加容易理解其需求, 比如

行为驱动开发准备好了吗?

通过上面的数据范例(example)的表格是不是更加容易的理解当前case的意图了。当Feature和Example文件都完成后,借助于第三方的开源框架实现,比如Cucumber,jBehave,SpecFlow等把Feature和Example装换成代码,然后通过第层次的单元测试框架,比如JUnit,NUnit,Spock,RSpec,结合测试驱动开发,从而把业务代码的逻辑实现。真是一举多得。

笔者就以Cucumber和JUnit为例,举一个BDD的例子吧。大家对JUnit比较熟悉,但是对Cucumber可能会相对陌生一点,笔者就花一点笔墨,简单介绍了一下Cucumber。Cucumer是一个实现了BDD的一个框架,其支持下面的语言和框架集成,

行为驱动开发准备好了吗?

是不是感觉很强大啊!!!! 下面进入实战,

1. Maven库的依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>uk.co.claysnow</groupId>
 <version>1.0</version>
 <packaging>jar</packaging>
 <name>Cucumber-JVM Book ATM Example</name>
 <artifactId>atm-example</artifactId>
 <properties>
 <cucumber.version>1.2.0</cucumber.version>
 <junit.version>4.11</junit.version>
 <picocontainer.version>2.14.2</picocontainer.version>
 </properties>
 <dependencies>
 <dependency>
 <groupId>info.cukes</groupId>
 <artifactId>cucumber-junit</artifactId>
 <version>${cucumber.version}</version>
 <scope>test</scope>
 </dependency>
 <dependency>
 <groupId>info.cukes</groupId>
 <artifactId>cucumber-picocontainer</artifactId>
 <version>${cucumber.version}</version>
 <scope>test</scope>
 </dependency>
 <dependency>
 <groupId>org.picocontainer</groupId>
 <artifactId>picocontainer</artifactId>
 <version>${picocontainer.version}</version>
 <scope>test</scope>
 </dependency>
 </dependencies>
 <build>
 <plugins>
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-surefire-plugin</artifactId>
 <version>2.12.2</version>
 <configuration>
 <argLine>-Duser.language=en</argLine>
 <argLine>-Xmx1024m</argLine>
 <argLine>-XX:MaxPermSize=256m</argLine>
 <argLine>-Dfile.encoding=UTF-8</argLine>
 <useFile>false</useFile>
 </configuration>
 </plugin>
 </plugins>
 </build>
 </project>
 

2. 安装Cucumber Eclipse插件

为了支持Feature的Gherkin语法,我们需要在Eclipse安装下面的插件:

https://cucumber.io/cucumber-eclipse/update-site

具体安装方法,请到百度或者google搜索。下面看一个具体的例子:

3. Feature文件

Feature: Cash Withdrawal
 Scenario: Successful withdrawal from an account in credit
 Given I have deposited $100.00 in my account
 When I withdraw $20
 Then $20 should be dispensed
 

4. 生成的Java Specification文件

import cucumber.api.java.en.*;
 import cucumber.api.Transform;
 import org.junit.*;
 import support.KnowsTheDomain;
 import transforms.MoneyConverter;
 public class AccountSteps {
 KnowsTheDomain helper;
 public AccountSteps(KnowsTheDomain helper) {
 this.helper = helper;
 }
 @Given("^I have deposited (\\$\\d+\\.\\d+) in my account$")
 public void iHaveDeposited$InMyAccount(@Transform(MoneyConverter.class) Money amount) 
 throws Throwable {
 helper.getMyAccount().deposit(amount);
 Assert.assertEquals("Incorrect account balance -", amount, helper.getMyAccount().getBalance()); 
 }
 }
 
mport cucumber.api.java.en.*;
 import org.junit.*;
 import support.KnowsTheDomain;
 import transforms.MoneyConverter;
 public class CashSlotSteps {
 KnowsTheDomain helper;
 public CashSlotSteps(KnowsTheDomain helper) {
 this.helper = helper;
 }
 @Given("^\\$(\\d+) should be dispensed$")
 public void $ShouldBeDispensed(int dollars) throws Throwable {
 Assert.assertEquals("Incorrect amount dispensed -", dollars, 
 helper.getCashSlot().getContents());
 }
 }
 
import cucumber.api.java.en.*;
 import support.KnowsTheDomain;
 public class TellerSteps {
 KnowsTheDomain helper;
 public TellerSteps(KnowsTheDomain helper) {
 this.helper = helper;
 }
 @When("^I withdraw \\$(\\d+)$")
 public void iWithdraw$(int amount) throws Throwable {
 helper.getTeller().withdrawFrom(helper.getMyAccount(), amount);
 }
 }
 

5. Cucumber 测试的运行入口

import cucumber.api.junit.Cucumber;
 import cucumber.api.CucumberOptions;
 import cucumber.api.SnippetType;
 import org.junit.runner.RunWith;
 @RunWith(Cucumber.class)
 @CucumberOptions(plugin="pretty", snippets=SnippetType.CAMELCASE)
 public class RunCukesTest {
 }
 

6. 具体的实现

public class Account {
 private Money balance = new Money();
 public void deposit(Money amount) {
 balance = balance.add(amount);
 }
 public Money getBalance() {
 return balance;
 }
 }
 public class CashSlot {
 private int contents;
 public int getContents() {
 return contents;
 }
 public void dispense(int dollars){
 contents = dollars;
 }
 }
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 public final class Money {
 private final int dollars;
 private final int cents;
 public Money() {
 this.dollars = 0;
 this.cents = 0;
 }
 public Money(int dollars, int cents) {
 this.dollars = dollars;
 this.cents = cents;
 }
 public Money(String amount) {
 Pattern pattern = Pattern.compile("^[^\\d]*([\\d]+)\\.([\\d][\\d])$");
 Matcher matcher = pattern.matcher(amount);
 matcher.find();
 this.dollars = Integer.parseInt(matcher.group(1));
 this.cents = Integer.parseInt(matcher.group(2));
 }
 public int dollars() {
 return dollars;
 }
 public int cents() {
 return cents;
 }
 public Money add(Money amount){
 int newCents = cents + amount.cents();
 int newDollars = dollars + amount.dollars();
 if (newCents >= 100){
 newCents -= 100;
 newDollars++;
 }
 return new Money(newDollars, newCents);
 }
 public Money minus(Money amount){
 int newCents = cents - amount.cents();
 int newDollars = dollars - amount.dollars();
 if (newCents < 0){
 newCents += 100;
 newDollars--;
 }
 return new Money(newDollars, newCents);
 }
 @Override
 public boolean equals(Object other){
 boolean equal = false;
 if (other instanceof Money){
 Money otherMoney = (Money)other;
 equal = (this.dollars() == otherMoney.dollars() 
 && this.cents() == otherMoney.cents());
 }
 return equal;
 }
 @Override 
 public String toString() {
 return String.format("$%01d.%02d", this.dollars(), this.cents());
 } 
 }
 public class Teller {
 private CashSlot cashSlot;
 public Teller(CashSlot cashSlot) {
 this.cashSlot = cashSlot;
 }
 public void withdrawFrom(Account account, int dollars) {
 cashSlot.dispense(dollars);
 }
 }
 
 

从上面的例子可以看出,其实现的本质和原理如下:

行为驱动开发准备好了吗?

夜深了,该睡了,行为驱动开发的介绍过一段落,行为驱动开发(BDD)你准备好了吗?


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法竞赛入门经典

算法竞赛入门经典

刘汝佳 / 清华大学出版社 / 2009-11 / 24.00元

《算法竞赛入门经典》是一本算法竞赛的入门教材,把C/C++语言、算法和解题有机地结合在了一起,淡化理论,注重学习方法和实践技巧。全书内容分为11章,包括程序设计入门、循环结构程序设计、数组和字符串、函数和递归、基础题目选解、数据结构基础、暴力求解法、高效算法设计、动态规划初步、数学概念与方法、图论模型与算法,覆盖了算法竞赛入门所需的主要知识点,并附有大量习题。书中的代码规范、简洁、易懂,不仅能帮助......一起来看看 《算法竞赛入门经典》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具