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

简介: 如果说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场景的正确性、无二义性、可执行性

组织

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

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

参考



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


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



相关文章
|
存储 JSON NoSQL
解锁JSON的奇妙世界:从基础到高级应用,一文搞懂JSON的妙用(下)
解锁JSON的奇妙世界:从基础到高级应用,一文搞懂JSON的妙用(下)
472 0
|
2月前
|
存储 SQL 机器学习/深度学习
ClickHouse不止于快:它在AI领域悄悄做了这些大事!
在第16届中国数据库技术大会(DTCC2025)大会上,ClickHouse Inc技术总监王鹏程,根据自己和团队在ClickHouse的技术实践经历,发表了题为《ClickHouse在AI领域的进展和应用》的主题演讲,分享了ClickHouse在现代数据架构中的创新应用,特别是在向量搜索、智能代理分析、机器学习数据管理等关键领域的突破。本文由ITPUB整理,经王鹏程老师授权发布。以下为演讲实录。
274 0
ClickHouse不止于快:它在AI领域悄悄做了这些大事!
|
弹性计算 负载均衡 数据库
阿里云轻量应用服务器收费标准、性能及适用场景全面解析
阿里云轻量应用服务器(Simple Application Server)作为面向个人开发者、中小企业等用户的入门级云产品,凭借其易用性、高性价比以及一站式服务体验,受到了广泛的欢迎。本文将全面解析阿里云轻量应用服务器的收费标准、最新活动价格以及适用场景,帮助用户更好地了解和选择这一产品。
阿里云轻量应用服务器收费标准、性能及适用场景全面解析
|
Kubernetes Linux 容器
kubernetes中不可见的OOM
kubernetes中不可见的OOM
150 5
|
12月前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
数据采集 JavaScript 前端开发
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
爬虫技术是数据采集的关键手段。针对动态加载的网页,传统HTTP请求及HTML解析难以满足需求。本文章介绍如何利用ClearScript V8库在.NET环境中执行复杂的JavaScript逻辑,以提高爬虫对动态内容的抓取效率。文章首先概述了ClearScript V8的功能,如何处理如微博这类含有大量动态加载内容的网站。通过使用代理IP、设置cookie和user-agent等方式模拟真实用户访问,确保了爬虫的稳定性和隐蔽性。提供了一个具体的C#爬虫示例,演示如何结合ClearScript V8和HTTP客户端来实现上述功能。这种方法不仅增强爬虫的灵活性,也极大地提高数据采集的效率和可靠性。
446 1
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
|
SQL 存储 大数据
Flink CDC中Starroks和doris哪个强一点?
Flink CDC中Starroks和doris哪个强一点?
1512 1
|
SQL 关系型数据库 分布式数据库
rds迁移与扩展
rds迁移与扩展
288 12
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
454 10
|
存储 缓存 Cloud Native
阿里云 ClickHouse 企业版云原生 ClickHouse 技术揭秘
云数据库 ClickHouse 企业版是阿里云和 ClickHouse, Inc 战略合作打造的云原生ClickHouse 产品。企业版推出专属 SharedMergeTree 云原生引擎,支持存算分离,Serverless 秒级实时弹性,集群吞吐和查询效率线性扩展及 Lightweight update 实时更新能力。本文将详细揭秘 SharedMergeTree 实现机制,实时弹性扩展实现原理,lightweight update 技术实现原理,同时对企业版和开源版进行详细的性能测试对比。
2205 1
阿里云 ClickHouse 企业版云原生 ClickHouse 技术揭秘