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

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


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



相关文章
|
Web App开发 iOS开发 开发者
Mac——基于Similator和Safari调试移动端页面
最近在开发移动端,需要在iphone环境下做一些调试,查看下是否有问题,但是手头上没有真机,不过当前主力本换成了`Mac`,所以就可以先用`Simulator`来调试下。
753 8
|
人工智能 安全 Nacos
MSE 企业版:全面拥抱 AI,SLA 99.99%,零信任安全
微服务引擎注册配置中心铂金版正式发布,支持Nacos 3.0 MCP服务动态注册与调优,提供比专业版更高的稳定性与安全能力,SLA达99.99%,服务推送性能提升300%。针对关键业务,铂金版通过独享核心资源实现更高规格配额,满足大规模需求。此外,新增MCP动态注册、HTTP服务转换、实时更新调优等功能,并强化数据源管理与安全能力,助力企业应对复杂业务挑战。
|
弹性计算 负载均衡 数据库
阿里云轻量应用服务器收费标准、性能及适用场景全面解析
阿里云轻量应用服务器(Simple Application Server)作为面向个人开发者、中小企业等用户的入门级云产品,凭借其易用性、高性价比以及一站式服务体验,受到了广泛的欢迎。本文将全面解析阿里云轻量应用服务器的收费标准、最新活动价格以及适用场景,帮助用户更好地了解和选择这一产品。
阿里云轻量应用服务器收费标准、性能及适用场景全面解析
|
存储 机器学习/深度学习 人工智能
文档智能与RAG技术在LLM中的应用评测
本文介绍了阿里云在大型语言模型(LLM)中应用文档智能与检索增强生成(RAG)技术的解决方案,通过文档预处理、知识库构建、高效检索和生成模块,显著提升了LLM的知识获取和推理能力,尤其在法律、医疗等专业领域表现突出。
1253 1
|
数据采集 JavaScript 前端开发
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
爬虫技术是数据采集的关键手段。针对动态加载的网页,传统HTTP请求及HTML解析难以满足需求。本文章介绍如何利用ClearScript V8库在.NET环境中执行复杂的JavaScript逻辑,以提高爬虫对动态内容的抓取效率。文章首先概述了ClearScript V8的功能,如何处理如微博这类含有大量动态加载内容的网站。通过使用代理IP、设置cookie和user-agent等方式模拟真实用户访问,确保了爬虫的稳定性和隐蔽性。提供了一个具体的C#爬虫示例,演示如何结合ClearScript V8和HTTP客户端来实现上述功能。这种方法不仅增强爬虫的灵活性,也极大地提高数据采集的效率和可靠性。
472 1
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
|
传感器 机器学习/深度学习 人工智能
人工智能中的Agent技术解析
【8月更文挑战第18天】总之,Agent作为人工智能领域的重要分支,将在未来发挥更加重要的作用。随着技术的不断进步和应用场景的不断拓展,Agent技术将为我们带来更加智能、便捷和高效的生活体验。
1991 3
|
SQL 关系型数据库 分布式数据库
rds迁移与扩展
rds迁移与扩展
310 12
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
483 10
|
自然语言处理 Java
Java中的行为驱动开发(BDD)实践
Java中的行为驱动开发(BDD)实践
|
测试技术 持续交付 开发工具
在阿里,我们如何管理代码分支?
阿里有很多的研发团队,不同事业部使用的发布流程、分支策略并非整齐划一,但总体上看是比较规整的。其中有一种主流的发布模式以及对应的分支使用方式,称为“AoneFlow”。这套工作模式思路独特,在阿里以外的地方并不多见。本文围绕这些实践,聊一聊分支管理的话题。
35076 61