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

简介: 如果说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)首发,转载需注明来源!


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



目录
相关文章
|
前端开发 测试技术 持续交付
云效平台介绍
云效,创立于2012年,是由阿里巴巴出品,是业内领先的面向企业的一站式研发效能平台,以提升研发效能为目标,通过线上化,透明化和自动化打通产品质量闭环,真正实现了持续集成持续交付。
10331 14
|
12月前
|
运维 监控 数据可视化
使用阿里云操作系统控制台排查内存溢出
操作系统控制台是阿里云最新推出的一款智能运维工具,专为提升运维效率、优化服务器管理而设计。它集成了多种运维管理功能,包括操作系统助手、插件管理器以及其他实用工具,为用户提供一站式的运维解决方案。无论是个人开发者还是企业运维团队,都可以通过这一平台轻松管理服务器和操作系统。
432 18
 使用阿里云操作系统控制台排查内存溢出
|
Web App开发 iOS开发 开发者
Mac——基于Similator和Safari调试移动端页面
最近在开发移动端,需要在iphone环境下做一些调试,查看下是否有问题,但是手头上没有真机,不过当前主力本换成了`Mac`,所以就可以先用`Simulator`来调试下。
1103 8
|
弹性计算 负载均衡 数据库
阿里云轻量应用服务器收费标准、性能及适用场景全面解析
阿里云轻量应用服务器(Simple Application Server)作为面向个人开发者、中小企业等用户的入门级云产品,凭借其易用性、高性价比以及一站式服务体验,受到了广泛的欢迎。本文将全面解析阿里云轻量应用服务器的收费标准、最新活动价格以及适用场景,帮助用户更好地了解和选择这一产品。
阿里云轻量应用服务器收费标准、性能及适用场景全面解析
|
存储 机器学习/深度学习 人工智能
文档智能与RAG技术在LLM中的应用评测
本文介绍了阿里云在大型语言模型(LLM)中应用文档智能与检索增强生成(RAG)技术的解决方案,通过文档预处理、知识库构建、高效检索和生成模块,显著提升了LLM的知识获取和推理能力,尤其在法律、医疗等专业领域表现突出。
1384 1
|
数据采集 JavaScript 前端开发
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
爬虫技术是数据采集的关键手段。针对动态加载的网页,传统HTTP请求及HTML解析难以满足需求。本文章介绍如何利用ClearScript V8库在.NET环境中执行复杂的JavaScript逻辑,以提高爬虫对动态内容的抓取效率。文章首先概述了ClearScript V8的功能,如何处理如微博这类含有大量动态加载内容的网站。通过使用代理IP、设置cookie和user-agent等方式模拟真实用户访问,确保了爬虫的稳定性和隐蔽性。提供了一个具体的C#爬虫示例,演示如何结合ClearScript V8和HTTP客户端来实现上述功能。这种方法不仅增强爬虫的灵活性,也极大地提高数据采集的效率和可靠性。
537 1
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
|
开发者 iOS开发 计算机视觉
如何将应用上传到TestFlight
如何将应用上传到TestFlight
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
514 10
|
自然语言处理 Java
Java中的行为驱动开发(BDD)实践
Java中的行为驱动开发(BDD)实践
|
存储 算法 程序员
计算机组成原理<五>——存储系统(二)
计算机组成原理<五>——存储系统
计算机组成原理<五>——存储系统(二)