| 编辑推荐: | 
                                   
                                   
                                    本文来自于云栖社区,本文主要介绍了行为驱动开发BDD,如何确保达成共识,以及BDD的方法介绍,希望对您的学习有所帮助。  | 
                                   
                                  | 
                             
                           
                          行为驱动开发(Behavior-Driven Development, 
                            BDD),是一种敏捷开发的技术,想必大多数同学都对敏捷开发领域中另一技术,测试驱动开发(Test-Driven 
                            Development,TDD)较为熟悉。 
                           TDD的思想原则是,首先先编写单元测试,当然在没有开发功能代码之前,一定是一个失败的测试;然后再编写功能代码,想方设法让测试可以通过;再重构代码去除重复的部分。 
                            
                          图片来自cucumber官网 
                           TDD的思想打破了传统开发的流程,好处也不言而喻。提高代码质量,可迅速发现并定位bug。 
                           BDD是建立在测试驱动开发基础之上,先编写验收测试,所用语言也是团队成员(业务、产品、开发、测试等)都可以读懂的实例,再进行上述TDD的流程。 
                              
                          图片源自《行为驱动开发课件》 
                          
                            如果说TDD是让我们正确的做事,那么BDD就是让我们做正确的事。 
                          BDD目的:在业务和开发之间达成共识。 
                          在软件项目中涉及多人紧密协作,由产品业务讲解功能需求,开发负责代码实现,测试保证软件质量,高质量的沟通对项目成功至关重要。如果在一个项目中业务人员用自己行话,开发人员用技术语言、技术思维去理解业务,在沟通过程难免出现分歧,开发人员就可能按自己的理解去实现了一个错误的功能。 
                              
                          如何确保达成共识? 
                          BDD的方法: 
                          用通用自然语言描述实例(系统行为) 
                          团队成员使用统一、易读的语言明确实例,作为验收测试标准。一方面可以消除理解上的歧义,一方面可以激发思考没有考虑到的场景。 
                          活文档 
                          这里的实例是可以随时运行,反馈系统运行真实结果,如果运行失败,要么文档过时需要更新,要么系统出现问题需要修复。 
                          BDD的实现,Cucumber是BDD的一个优秀开源框架。 
                          Cucumber是一款协作工具。 
                          支持多种开发语言Java C++ Ruby python等等 
                          它是一个命令行工具。运行是从特性feature文本中解析要测试的场景scenario,每个场景由一系列的步骤step组成,cucumber一步步执行这些步骤,得到最终的测试结果。 
                          Cucumber的使用 
                          环境准备: 
                            JavaSE(java9还不支持) 
                          Maven 3.31以上 
                          IntellJ IDEA 安装cucumber for java 插件 
                          创建一个maven项目,讲cucumber-jvm依赖添加到pom文件中 
                          
                             
                              <dependency>  
                                <groupId>junit</groupId>  <artifactId>junit</artifactId>  
                                <version>4.11</version> 
                                </dependency> 
                                <dependency>  <groupId>info.cukes</groupId>  
                                <artifactId>cucumber-java</artifactId>  
                                <version>1.2.5</version> 
                                </dependency> 
                                <dependency>  <groupId>info.cukes</groupId>  
                                <artifactId>cucumber-junit</artifactId>  
                                <version>1.2.5</version>  <scope>test</scope> 
                                </dependency> 
                                ?  | 
                             
                           
                          
                            创建一个特性文件。 
                            user.feature文件,功能是管理员给系统新增用户账号,并判断账号创建成功 
                          
                             
                              #language:zh-CN 
                                @api@user 
                                功能:管理员给系统新增用户账号 
                                场景大纲:创建用户账号 
                                当 管理员新建用户账号"<accountName>"手机号"<mobile>" 
                                那么 他应该可以查询到该账号"<accountName>" 
                                例子: 
                                |accountName|mobile| 
                                |test|11111111111|  | 
                             
                           
                          
                            特性文件必须以.feature为后缀 
                          #language:zh-CN说明使用的是中文简体语言,cucumber支持50多种语言。不注明的情况默认是英文。 
                          通过java cucumber.api.cli.Main --i18n--help可以查支持的语言。 
                          但由于相关jar包并没有在classpath中,执行会直接报错误: 找不到或无法加载主类 cucumber.api.cli.Main 
                          把相关jar包放在一个jar文件夹中,创建一个cucumber.bat文件,内容如下: 
                          java -cp "./jars/*" cucumber.api.cli.Main 
                            %*,再执行就可以正常运行了 
                              
						  @api@user,是标签,可以将场景归类,在执行测试时也可以方便指定执行哪个标签的场景。 
                          查看一下中文支持的关键词 
                              
                          创建步骤定义。 
                            运行测试mvn clean test,cucumber会直接告诉我有1个场景没有定义,2个步骤没有定义 
                           
                          并且告诉需要实现哪些缺失的steps 
                            
                          复制提示缺失的step的代码,到ApiStepdefs文件中,文件命名什么无关紧要。 
                            再次运行mvn clean test,结果是 第一个步骤pending,下一步需要去实现step 
                            
                          好我们开始写一个失败的rest api的测试,并执行。 
                          
                             
                               @当("^管理员新建用户$") 
                                public void 管理员新建用户(List<User> users) throws 
                                Throwable { 
                                for(User user:users){ 
                                apiHelper.post("/api/adduser",user); 
                                apiHelper.expectStatus(201);
                                 }?  | 
                             
                           
                            
                          还没有去开发这个rest api服务。这里使用的spring boot框架开发rest api服务。开始采用TDD的方式,先写一个失败的测试 
                          
                             
                              @RunWith(SpringRunner.class) 
                                @SpringBootTest 
                                @AutoConfigureMockMvc 
                                public class UserControllerTest { 
                                @Autowired 
                                private MockMvc mvc; 
                                @Test 
                                public void addUserAddsearch() throws Exception 
                                { 
                                User user = new User(); 
                                String username = "test"; 
                                user.setAccountName(username); 
                                user.setMobile("11111111111");
                                 String userInJson = JSON.toJSONString(user); 
                                  System.out.println(userInJson); 
                                  mvc.perform(post("/api/adduser") 
                                  .contentType(MediaType.APPLICATION_JSON) 
                                  .accept(MediaType.APPLICATION_JSON) 
                                  .content(userInJson)) 
                                  .andDo(print()) 
                                  .andExpect(status().isCreated()); 
                                 } 
                                  }   | 
                             
                           
                           执行测试,断言失败返回404。 
                           
                          继续写rest api服务实现,运行测试,使得测试通过。 
                         
                             
                              @RestController 
                                public class UserController { 
                                @Autowired 
                                private UserService userService;
                                 @RequestMapping(value = "/api/adduser", 
                                  method = RequestMethod.POST, produces = "application/json") 
                                  @ResponseStatus(HttpStatus.CREATED) 
                                  public void create(@RequestBody User user) { 
                                  userService.create(user); 
                                  } 
                                 }   | 
                             
                           
                          
                            启动spring-boot服务 mvn spring-boot:run; 
                          再运行test工程中的bdd测试代码,这次的结果是第一步pass,第二步 
                            pending。 
                            
                          
                            再按照上面的方式,继续完成第二步。最终结果2个步骤都通过。 
                          
						  
                            查看测试报告 
                              
                          思考: 
                           行为驱动开发能帮助团队快速构建和交付更多有价值和高质量的产品。 
                           目前产品开发过程依然是瀑布式需求-设计-开发-测试-验收。如使用BDD的实践,我 
                          们会有哪些改变。 
                             
                          想引入BDD的开发到自己的产品线开发实践中,还会有很长的路要走,中间过程免不了遇到各种阻力。 
                              
                            
                           |