敏捷课堂 | 行为驱动开发,让开发做正确的事

简介: 如果说TDD是让我们正确的做事,那么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的实践,我

们会有哪些改变。

参与角色

现在

未来

产品

输出需求说明书与交互文档demo

输出用户故事地图

描述产品的用户故事

产品、开发、测试

产品需求评审

编写自然语言描述的特性文件(feature)

作为验收测试标准

开发

系统设计、代码实现

根据feature中的场景驱动开发过程,

编写单元测试,编写实现细节,

保持最简单设计,不断重构。

测试

测试用例设计

使用Cucumber工具,

使得feature变为可执行的程序。

测试

执行测试用例

以自动化验收测试作为最基础测试。

进行探索性测试及其他非功能性测试。

产品、开发、测试

文档基本在项目开始或后期没有人持续维护

自动化验收测试的报告永远保持最新的文档

想引入BDD的开发到自己的产品线开发实践中,还会有很长的路要走,中间过程免不了遇到各种阻力。

角色

可能的困难

开发

已经习惯性使用原有的开发模式和思维,难以接受新的思想

产品

对敏捷中的实例化需求不知如何下手

测试

要与产品开发更紧密的协助,确保feature场景的正确性、无二义性、可执行性

组织

是否允许、是否肯下决心去做新的尝试,新方式的引入是否影响现有项目进度,各种排异性是否会使项目变得更糟

  任何一种变革都不会轻而易举地实现,是否有决心去尝试以获得更大的收益? 

参考

  • 敏捷开发系列课(四)《行为驱动开发》-问菊老师课程
  • 《Cucumber行为驱动开发指南》
  • https://cucumber.io/官网



作者:张蕊,阿里影业-测试专家 ,文章系云效微信公众号(ali_yunxiao)首发,转载需注明来源!


更多敏捷课堂内容,关注云效微信公众账号



相关文章
|
25天前
|
项目管理 UED
高效协作工具推荐:让你的团队在新春事半功倍
新春伊始,各行各业迎来开工大吉。为帮助团队迅速进入高效协作状态,本文推荐几款高效协作工具,涵盖项目管理、沟通、文档协作和时间管理等,特别介绍板栗看板的独特优势。选择合适的工具需考虑团队规模、项目复杂度和预算,助力团队提升效率,实现更好业绩。
41 10
|
4月前
|
敏捷开发 监控 数据可视化
看板工具提升产研团队工作效率实操
本文介绍了看板管理在产品研发团队中的应用价值,通过可视化方式呈现任务状态,提高团队协作效率。文章详细解析了五种看板的应用场景,包括Sprint Board、产品迭代计划、用户反馈收集、周报看板及项目整体进度看板,旨在帮助团队更高效地管理和推进项目。
63 1
看板工具提升产研团队工作效率实操
|
9月前
|
数据采集 前端开发 数据可视化
程序员必知:基于氚云平台的应用开发学习(一)
程序员必知:基于氚云平台的应用开发学习(一)
273 0
|
10月前
|
敏捷开发 持续交付
【软件工程】走进敏捷开发:灵活、协作、迭代的软件工艺之旅
【软件工程】走进敏捷开发:灵活、协作、迭代的软件工艺之旅
|
10月前
|
前端开发 IDE JavaScript
【inBuilder 低代码开发实验室】使用inbuilder完成UBML低代码设计开发
【inBuilder 低代码开发实验室】使用inbuilder完成UBML低代码设计开发
133 0
|
供应链 项目管理 智能硬件
|
数据可视化 前端开发 数据管理
OushuDB 小课堂丨低代码和无代码开发是解决生产力困境的方法吗?
OushuDB 小课堂丨低代码和无代码开发是解决生产力困境的方法吗?
116 0
|
JavaScript 前端开发 大数据
1.2项目评选系统的低代码基础|学习笔记(一)
快速学习1.2项目评选系统的低代码基础
1.2项目评选系统的低代码基础|学习笔记(一)
|
运维 JavaScript 前端开发
1.2项目评选系统的低代码基础|学习笔记(二)
快速学习1.2项目评选系统的低代码基础
1.2项目评选系统的低代码基础|学习笔记(二)
|
敏捷开发 数据可视化 项目管理
Computer:敏捷开发Scrum方法的简介、发展历程、开发流程之详细攻略
Computer:敏捷开发Scrum方法的简介、发展历程、开发流程之详细攻略
Computer:敏捷开发Scrum方法的简介、发展历程、开发流程之详细攻略