当前位置: 首页 > news >正文

基于Cucumber的行为驱动开发(BDD)实例

本篇介绍 Cucumber 的基本使用, 因为Cucumber是BDD的工具, 所以首先需要弄清楚什么是BDD,而在介绍BDD之前,先看看常见的软件开发方法。

常见的软件开发方法

  • 面向过程开发(Procedural Development):面向过程开发注重流程和功能的实现,而不是业务需求的实现。
  • 面向对象开发(Object-Oriented Development):面向对象开发注重对象之间的交互和关系,而不是业务需求的实现。
  • 测试驱动开发(Test-Driven Development,TDD):TDD注重测试用例的编写和通过测试用例来驱动代码的实现,而不是业务需求的实现。
  • 行为驱动开发(Behavior-Driven Development,BDD):BDD注重业务需求和行为,并通过测试用例来验证和定义业务需求的实现。

BDD的由来

BDD是行为驱动开发的缩写。它是一种软件开发方法,强调开发人员、测试人员和业务利益相关者之间的协作,以确保正在开发的软件与业务目标相一致。
BDD是在2003年由Dan North首次提出的。他发现在软件开发中,注重测试和自动化并不足以确保软件的质量和正确性。因此,他提出了一种基于“Behavior”(行为)的开发方法,即BDD。BDD旨在通过强调需求和业务价值,更紧密地结合开发和测试团队,提高软件的质量和客户满意度。
BDD涉及使用自然语言描述或所需系统行为的示例,这些示例被翻译成自动化测试,以确保系统的行为符合预期。这种方法有助于确保软件的开发是在清楚地理解所需的行为和结果的情况下进行的,以满足所有利益相关者的需求。

Cucumber 是什么

在这里插入图片描述

Cucumber 是一个行为驱动开发(BDD)工具,用于创建和运行自动化测试,以确保软件系统的行为符合业务需求和用户期望。它用自然语言编写测试用例,这些测试用例可以与开发和业务团队共享和理解。Cucumber支持多种编程语言,并且可以与各种测试框架集成。

Cucumber用于描述应用程序的行为、功能和需求。它的目标是帮助开发人员和非技术人员之间的沟通,以及帮助开发人员编写更易于维护的测试代码。通过使用Cucumber,团队可以创建基于真实场景的自动化测试,这些测试使用了普通语言来描述行为,因此它们对所有团队成员来说都是可理解的。以下是Cucumber的一些特点和用途:

特点:

  • 支持普通语言:Cucumber用于编写测试的语言是Gherkin,这是一种自然语言风格的语言,专门设计用来描述业务行为而不需要注入具体的如何实现。因此,非技术的团队成员(比如产品经理和业务分析师)也能参与测试和开发的过程。

  • 支持多种语言:尽管Cucumber起初是为用Ruby写的项目设计的,但是现在已经支持多种编程语言,包括Java, JavaScript, .NET,等。

  • 支持多种测试框架和工具,包括Selenium和Appium。

  • 可以生成易于阅读的测试报告,并提供了可视化的测试结果。

  • 整合支持:Cucumber可以和许多流行的持续集成/持续部署工具整合,例如Jenkins和TeamCity。

  • 可维护性与重用性:Cucumber的测试案例是用普通话写的,所以它们是可理解的,并且可以重复使用。此外,因为测试案例直接对应到需求,所以他们很容易维护。

用途:

  • 协助团队沟通:Cucumber使用自然语言描述应用程序的需求和功能,可以帮助开发人员和非技术人员之间的沟通。
  • 自动化测试:使用Cucumber可以编写自动化测试用例,这些测试用例模拟了用户使用应用程序的场景,以确保应用程序的正确性。
  • 生成文档:Cucumber测试用例描述了应用程序的行为和需求,可以作为应用程序的文档。
    总之,Cucumber是一款功能强大的BDD工具,可以帮助开发团队更好地协作、编写高质量的测试用例和文档。

基于Java 语言的Cucumber 使用实例

这里使用基于Maven的项目为例, 在Eclipse 上进行开发。

步骤如下:

  1. 导入依赖

需要导入 cucumber-java 和 cucumber-junit , 这里导入当前最新版本 7.14.0。

		<dependency><groupId>io.cucumber</groupId><artifactId>cucumber-java</artifactId><version>7.14.0</version></dependency><dependency><groupId>io.cucumber</groupId><artifactId>cucumber-junit</artifactId><version>7.14.0</version></dependency>
  1. 创建规格文件user.feature, 文件位于 src/test/resources 目录下:
Feature: UserScenario: createGiven User 100 not existWhen create User 100Then can query User 100

这个文件的解读是:
系统中User功能的 create场景, 如果ID为100的 User不存在,就创建这个User, 创建完成之后就可以查询到这个User了。

  1. 根据规格文件完成测试的代码,这里就是根据规格中的步骤定义的, 文件名为StepDefinitions.java。
/**
* @Title: StepDefinitions.java
* @Package com.osxm.je.topic.bdd
* @Description: TODO
* @author XM
* @date 2023年10月9日 下午10:03:34
* @Copyright: 2023
* @version V1.0  
*/
package com.osxm.je.topic.bdd;import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;import java.util.HashMap;
import java.util.Map;import com.osxm.je.basic.entity.User;import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;public class StepDefinitions {private Map<Integer, User> userRepo = new HashMap<Integer, User>();private User user;@Given("User {int} not exist")public void user_not_exist(Integer userId) {assertFalse(userRepo.containsKey(userId));}@When("create User {int}")public void create_user(Integer userId) {user = new User(userId);userRepo.put(userId, user);}@Then("can query User {int}")public void query_user(Integer userId) {user = userRepo.get(userId);assertNotNull(user);}
}
  • 注意 @Given 注解中使用 {int} 定义的变量和规格文件user.feature中的对应
  1. 编写测试入口类 CucumberTest.java
/**
* @Title: CucumberTest.java
* @Package com.osxm.je.topic.bdd
* @Description: TODO
* @author XM
* @date 2023年10月9日 下午10:05:35
* @Copyright: 2023
* @version V1.0  
*/
package com.osxm.je.topic.bdd;import org.junit.runner.RunWith;import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources")  // 要测试的 Feature 文件的位置
public class CucumberTest {}

运行测试后的效果如下:
在这里插入图片描述

如果将规格文件故意修改错误:

Feature: UserScenario: createGiven User 100 not existWhen create User 100Then can query User 200

则运行结果就是错误的, 如下图:
在这里插入图片描述



相关文章:

基于Cucumber的行为驱动开发(BDD)实例

本篇介绍 Cucumber 的基本使用&#xff0c; 因为Cucumber是BDD的工具&#xff0c; 所以首先需要弄清楚什么是BDD&#xff0c;而在介绍BDD之前&#xff0c;先看看常见的软件开发方法。 常见的软件开发方法 面向过程开发&#xff08;Procedural Development&#xff09;&#x…...

十六、代码校验(2)

本章概要 前置条件 断言&#xff08;Assertions&#xff09;Java 断言语法Guava 断言使用断言进行契约式设计检查指令前置条件后置条件不变性放松 DbC 检查或非常严格的 DbCDbC 单元测试 前置条件 前置条件的概念来自于契约式设计(Design By Contract, DbC), 利用断言机制…...

安卓 kotlin-supportFragmentManager报红

如果你继承baseActivity 请查看 是不是继承 AppCompatActivity...

linux中安装RocketMQ以及dashboard

前提&#xff1a; 需要安装jdk8 上传下面的文件到服务器中 新建目录 mkdir rocketmq 将下载后的压缩包上传到阿里云服务器或者虚拟机中去&#xff0c;并解压 unzip rocketmq-all-4.9.2-bin-release.zip 配置环境变量 vim /etc/profile 配置内容&#xff1a; export NAM…...

Android kotlin内联函数(inline)的详解与原理

一、介绍 在kotlin中&#xff0c;有一种函数叫内联函数&#xff0c;这种函数标识符是inline&#xff0c;但是好多人对这个函数的理解只停留在八股文中&#xff0c;内容函数的用法和普通函数没有区别&#xff0c;但是在编译原理上是有&#xff0c;对程序的性能有一定的影响。 二…...

林沛满---一个面试建议

在应聘一个技术职位之前&#xff0c;做好充分的准备无疑能大大提高成功率。这里所说的准备并不是指押题&#xff0c;因为有经验的面试官往往准备了海量的题库&#xff0c;押中的概率太低。比如我有位同事的题库里有上百道题&#xff0c;内容涵盖了编程、操作系统、网络、存储……...

CMake教程-第 5 步:安装和测试

CMake教程-第 5 步&#xff1a;安装和测试 1 CMake教程介绍2 学习步骤Step 1: A Basic Starting PointStep 2: Adding a LibraryStep 3: Adding Usage Requirements for a LibraryStep 4: Adding Generator ExpressionsStep 5: Installing and TestingStep 6: Adding Support f…...

移动应用-Android开发基础\核心知识点

Android开发基础 知识点 1 介绍了解2 系统体系架构3 四大应用组件4 移动操作系统优缺点5 开发工具6 配置工具7 下载相关资源8JDK下载安装流程9配置好SDK和JDK环境10 第一个Hello word11 AS开发前常用设置12模拟器使用运行13 真机调试14 AndroidUI基础布局15 加载展示XML布局16…...

Java读取并转换字符串中的浮点数

在写Android接收蓝牙数据的时候&#xff0c;由于传过来的蓝牙数据转换后都为字符串格式&#xff0c;但是需要从其中提取出来浮点数&#xff0c;所以通过查阅资料写出了从字符串中提取并转换为浮点数的方法&#xff0c;特记录下来以供参考。 目录 原始数据内容 提取字符串中的…...

SQL: 索引原理与创建索引的规范

SQL 索引是一种数据结构&#xff0c;用于加速数据库查询操作。它通过在表的列上创建索引&#xff0c;提供了一种快速查找数据的方法&#xff0c;减少了数据库的扫描和比较操作&#xff0c;从而提高了查询性能。索引根据其实现方式可以分为多种类型&#xff0c;如 B-树索引、哈希…...

基于STM32_DS18B20单总线传感器驱动

基于STM32_DS18B20单总线传感器驱动 文章目录 基于STM32_DS18B20单总线传感器驱动前言一、BS18B20&#xff1f;二、原理1.复位与检验2.基本命令3.唯一ROM识别码4.温度转换 三、驱动代码四、注意事项 前言 本文以一款典型的单总线传感器及其驱动——DS18B20为例&#xff0c;简单…...

目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型(三)

前言 目标识别如今以及迭代了这么多年&#xff0c;普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述&#xff0c;YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性…...

springboot线程池创建与使用

/*** author: zcs* Title: TaskPoolConfig* Description: 线程池配置* date: 2023/10/11 17:52*/ Component public class TaskPoolConfig {Bean(name "threadPoolTaskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor taskExecutor new ThreadP…...

UDP和TCP特点(部分)对比:

传输层的两个主要协议&#xff1a;TCP 和 UDP UDP和TCP特点&#xff08;部分&#xff09;对比&#xff1a; UDP&#xff1a;无连接&#xff0c; 不可靠传输&#xff0c; 面向数据报&#xff0c; 全双工。 TCP&#xff1a;有连接&#xff0c; 可靠传输&#xff0c; 面向字节流…...

PostMan环境变量、全局变量、动态参数使用

一、环境准备 postmanmoco [{"description": "登录认证","request": {"uri": "/login","method": "post","forms": {"user": "admin","password": "a123…...

服务器数据恢复-服务器硬盘指示灯黄灯闪烁的数据恢复案例

服务器数据恢复环境&#xff1a; 服务器面板上的硬盘指示灯显示黄色是一种警告&#xff0c;提示指示灯对应的服务器硬盘已经被服务器识别出存在故障&#xff0c;硬盘即将下线。如果出现这种情况&#xff0c;建议服务器管理员/运维人员及时用完好的硬盘替换显示黄色指示灯对应的…...

ts 分发

在 TypeScript 中&#xff0c;"分发"&#xff08;distributive&#xff09;是指在条件类型中的联合类型上自动进行类型推断的机制。当使用条件类型操作联合类型时&#xff0c;TypeScript 会自动将联合类型中的每个成员都应用该条件类型。 下面是一个示例&#xff1a…...

SQL中的group by使用注意事项

在 SQL 中&#xff0c;GROUP BY 语句用于将查询结果按照指定的列进行分组&#xff0c;并对每个分组计算聚合函数&#xff08;如 SUM、AVG、COUNT 等&#xff09;的值。一般情况下&#xff0c;如果查询中包含聚合函数&#xff0c;那么就需要使用 GROUP BY 语句将查询结果按照指定…...

矩阵剪辑系统源码----pc/手机端双开发

剪辑系统&#xff0c;剪辑矩阵系统&#xff0c;剪辑矩阵系统主要是针对抖音、快手、bili平台的一个工具&#xff0c;今天就来给大家交流一下这 个产品的主要功能以及构成。剪辑矩阵系统&#xff0c;矩阵剪辑系统源码-这产品主要功能就是一个视频剪辑功能&#xff0c;这个视频剪…...

0基础学习VR全景平台篇 第106篇:认识调色软件Lightroom

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 正式开讲之前需要先引出一个概念&#xff1a;到底什么是调色? 比如说上面这张照片&#xff0c;你可能会具体的指出照片中的元素有天空、山脉、草地等…… 如果我们跳出我们的固…...

Python开发者三步完成Taotoken API密钥配置与调用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Python开发者三步完成Taotoken API密钥配置与调用 对于希望快速接入大模型能力的Python开发者而言&#xff0c;Taotoken平台提供的…...

新手也能搞定!用Simulink搭建晶闸管直流调速系统(附完整模型文件)

从零构建晶闸管直流调速系统的Simulink实战指南 电力电子领域的研究生和工程师们常常需要快速掌握经典电路仿真技能。本文将手把手带你完成晶闸管直流调速系统的建模全过程&#xff0c;从模块选择到参数调试&#xff0c;每个环节都配有详细说明和实用技巧。不同于传统教材偏重理…...

ESP32+LVGL8.3保姆级教程:搞定ST7789V屏幕和CST816T触摸(附完整代码)

ESP32LVGL8.3实战指南&#xff1a;ST7789V屏幕与CST816T触摸的深度适配 当一块240x280分辨率的ST7789V屏幕与CST816T触摸芯片组合遇到ESP32开发板&#xff0c;如何让LVGL8.3图形库完美驱动这套硬件&#xff1f;本文将带你从零开始&#xff0c;穿越配置迷宫&#xff0c;解决色彩…...

Python 开发者五分钟接入 Taotoken 调用 GPT 与 Claude 模型指南

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Python 开发者五分钟接入 Taotoken 调用 GPT 与 Claude 模型指南 对于习惯使用 OpenAI 官方 Python SDK 的开发者来说&#xff0c;…...

(Python)Pandas reset_index() 实战解析:从数据混乱到索引清晰

1. 为什么你的Pandas数据总是乱糟糟&#xff1f; 每次处理完数据&#xff0c;看着那个乱七八糟的索引是不是特别头疼&#xff1f;我刚开始用Pandas的时候&#xff0c;经常遇到这样的问题&#xff1a;合并几个表格后索引重复了&#xff0c;分组统计后多出来一堆莫名其妙的层级&a…...

STM32 I2C驱动AT24C02 EEPROM:手把手教你搞定页边界对齐与连续读写(附完整代码)

STM32 I2C驱动AT24C02 EEPROM&#xff1a;页边界对齐与连续读写实战指南 在嵌入式开发中&#xff0c;EEPROM因其非易失性存储特性成为参数保存的首选方案。而AT24C02作为经典的I2C接口EEPROM&#xff0c;其页写入机制却暗藏玄机——许多开发者第一次遭遇"写入数据丢失&quo…...

SLO-Warden:基于错误预算的智能SLO守护平台设计与实践

1. 项目概述&#xff1a;一个面向SLO的智能守护者在云原生和微服务架构成为主流的今天&#xff0c;服务的稳定性和可靠性不再是“锦上添花”&#xff0c;而是“生死攸关”的底线。作为一线的运维工程师或SRE&#xff0c;我们每天都在和各种监控指标、告警风暴作斗争。传统的监控…...

OpenClaw 落地企业微信:AI 驱动办公,效率提升看得见

前言 在企业数字化办公场景下&#xff0c;将智能对话功能与企业微信集成可有效提升内部沟通效率和业务响应速度。本文系统阐述了OpenClaw与企业微信的对接方案&#xff0c;该方案采用可视化操作界面实现智能机器人的快速部署&#xff0c;助力企业便捷构建专属AI助手&#xff0…...

从PCB走线到连接器:手把手教你用ADS仿真优化S参数(避坑SI/PI设计)

从PCB走线到连接器&#xff1a;用ADS仿真优化S参数的实战指南 在高速数字电路和射频设计中&#xff0c;S参数就像设计师的"体检报告"&#xff0c;直观反映信号传输路径的健康状况。想象一下&#xff0c;当你设计的PCIe Gen4接口在实验室测试时出现信号完整性问题&am…...

告别卡顿!用MobaXterm+PyCharm专业版,在实验室服务器上丝滑跑Python的保姆级教程

实验室服务器远程开发终极指南&#xff1a;MobaXterm与PyCharm专业版的高效协作方案 当你的Python脚本在本地笔记本上跑得比蜗牛还慢&#xff0c;而实验室那台128核的服务器却在"闲置"时&#xff0c;这种资源错配简直让人抓狂。作为一名常年与远程服务器打交道的算法…...