测试驱动编程(3)进阶单元测试(下)

文章目录

    • 测试驱动编程(3)进阶单元测试(下)
      • 示例实战
        • 接收同事的需求
        • 开始迭代需求
          • 故事迭代1
          • 故事迭代2
          • 故事迭代3
          • 故事迭代4
          • 故事迭代5
          • 故事迭代6

测试驱动编程(3)进阶单元测试(下)

示例实战

接收同事的需求

你的同事正在开发一个远程控制轮船的程序,他已经完成了一部分工作,但是他休假去了, 现在任务交给了你。你的同事是一个TDD的践行者,你接下来要在他完成的工作基础上继续开发

下图是你同事设计的几个主要的类:

  • Ship:表示轮船,目前没有任何方法,继续要迭代的地方
  • Point:表示二维坐标
  • Direction:代表方向的枚举类以及左右转弯的方法
  • Planet:地球,轮船航行的地方,包含最大的航行坐标点以及分布了哪些障碍物设置
  • Location:轮船当前方位,包含所在的坐标以及当前的行驶方向,可以前进后退、进行航行

下面是你同事已经完成的测试验证方法,所以请你放心的改造下去

方向测试类

轮船行驶范围(地球)测试类

二维坐标测试类

方位(包含方向与二维坐标)测试类

控制方向和坐标参考系如下:

特别要注意的是地球是圆的,起点和终点是重叠的。例如:往x轴最远处前进将回到x=1的坐标点

开始迭代需求

上面看到同事之前写的代码所有测试经过都是绿灯,我们可以放心的进行后面的需求迭代了

故事迭代1

我们需要给定轮船的起始位置以及方向

因为每次控制轮船的提前肯定是要有一艘轮船,所以在每个测试方法前都应该需要一艘船,我们把它放在@BeforeEach注解的方法里

Ship默认只有无参的构造函数所以报错了,这也是正常的红-绿-重构阶段,接下来我们进入绿阶段

写一个测试方法测试下

故事迭代2

轮船可以前进或后退

在编写轮船可以前进后退的时候,我们是不是要编写各个方向的前进和后退测试方法呢?类似下面的

该测试方法测试的是轮船往北移动,Y轴的坐标将加1
实际上我们不应该这么去编写测试,原因有三:1,我们的测试方法的结果依赖了其它方法、类的内部工作原理(否则我们怎么知道y轴需要检测的是8);2,会导致编写多个测试方法,我们肯定要把东南西北各个方向相关的方法都写一遍;3,依赖的其它方法虽然经过测试,但是如果发生变化,我们需要找到调用这个方法的所有地方进行修改

这里我们可以巧妙利用已经存在的方位方法进行测试用例编写:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

编写moveForward()方法,使其变绿

轮船前进的完成了,后退的功能非常相似,就不详细说明了

故事迭代3

轮船可以左转或右转

和故事迭代2有点类似,在之前辅助类Location中包含了左右转的方法,我们可以结合实现

故事迭代4

轮船接收一个指令然后完成相应的动作(比如:lrfb表示左转右转前进再后退)

每个命令都用一个字符表示:f表示前进、b表示后退、l表示左转、r表示右转
先编写一个测试用例,接收一个字符串,解析并调用相关的方法

完成 的步骤后进入 绿

测试下结果没问题
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

故事迭代5

轮船行驶的地球是圆的,所以可以从一边的尽头跨越到另外一边

目前为止,轮船的构造函数只有一个参数location,代表轮船的方位,现在需要引入一个planet参数代表行驶的范围(水域大小)

新增一个两个参数的Ship构造函数,使其变绿

我们发现其实之前有过ship单个参数的测试方法,而且还有一个初始化方位的方法,其实我们可以将其重构成每次测试前都初始化一艘带方位和行驶范围的轮船

刚才的测试方法就可以简化为

Ship的构造参数也只需要保留一个就可以了

接下来编写一个往东边再前进回到x轴坐标1的测试方法,因为我们初始化的时候船就是朝东的,所以不同重新设置方向了

跑下测试用例肯定报错的,我们期望的是1,但是实际是51,超出边界了

度假中的同事之前已经在location辅助类中完成了跨越边界的逻辑,所以我们只要重构下ship中的前后形式方法,带上边界范围即可

运行下ship的所有测试方法,全部绿灯,故事迭代完成

故事迭代6

每次移动需要进行障碍检测,遇到障碍的话停在原处报告遇到的障碍

地球上的水域不是畅通无阻的,有暗礁和陆地,所以我们得在行驶区域中加入障碍物,轮船行驶的时候先检查是否有有障碍物

我们首先在初始化的时候在行驶区域内加入障碍物

重构下初始化的方法

无需添加实现,测试就可以通过
接下来我们测试有障碍物的时候,轮船无法行驶,我们的设计是让接收指令的方法返回一个字符串,代表每条指令的执行情况

根据测试代码,障碍物和船形式的路线如下:(先往蓝色箭头指示方向,后往绿色箭头指示方向)

执行下肯定是报错的,因为我们之前逻辑不支持障碍物,接下来要重构下我们的业务代码:
第一个地方:调用位置帮助类的时候,前进后退的方法要加上障碍物信息

第二个地方:指令接收方法要判断每次执行的结果,拼接成字符串返回

运行下我们的测试类

至此我们的遥控轮船开发完成,同事度假回来了,后面的需求交给他吧,毕竟我们也成为了TDD的践行者,让他放心的迭代吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PROXYCHAINS】Kali Linux 上配置NAT PROXYCHAINS保姆级教程

kali linux配置agent 在博主配置kali 的时候遇到了一些小问题,主要就是连接一直报错超时。 方法一:优点:免费,但是agent很不稳定 搜索免费ip,在Google搜索free proxy list 检查可用ip 连接成功 cd /etcls |grep redsnano reds…

IDEA中一些常见操作【持续更新】

文章目录 前言善用debugidea中debug按钮不显示自动定位文件【始终选择打开的文件】idea注释不顶格【不在行首】快速定位类的位置【找文件非常快】创建文件添加作者及时间信息快速跳转到文件顶端 底端 前言 因为这些操作偶尔操作一次,不用刻意记忆,有个印…

Gradle 基础学习(九) 认识Gradle属性和构建环境配置

Gradle提供了多种机制给开发者来配置Gradle自身的行为和具体项目的行为。 以下是使用这些机制的一些参考。 Mechanism Information Example Command line interface 命令行接口,用于动态配置构建行为和Gradle功能 --rerun Project properties 特定于Gradle …

Spring Cloud快速入门

Spring Cloud是一个用于构建微服务架构的开源框架,它基于Spring Boot,旨在简化分布式系统的开发。以下是Spring Cloud应用框架的快速入门步骤: 环境准备: 安装Java JDK:确保你的开发环境已经安装了Java JDK&#xff0c…

苹果CMS:怎么重新安装

当我们安装好苹果CMS之后苹果cms:介绍及安装,但是最好我们在安装的时候配置好对应配置后,备份一份,如果不记得哪里配置出了问题,出现一些不可预料的问题,那我们可以简单暴力的直接重新安装,我们…

Agency Swarm介绍:构建和管理智能代理的未来

随着人工智能技术的迅速发展,智能代理正在成为现实世界中不可或缺的一部分。Agency Swarm是一个由Arsenii Shatokhin(VRSEN)创建的开源框架,它简化了自定义智能代理的创建过程,并允许用户构建协作的代理群(…

211初试自命题复试线仅302分!延边大学计算机考研考情分析!

延边大学(Yanbian University),简称“延大”,地处吉林省延边朝鲜族自治州,是国家“双一流”建设高校、国家“211工程”重点建设大学、西部开发重点建设院校、吉林省人民政府和教育部共同重点支持建设大学、吉林省人民政…

计算机如何将输入文字显示出来的?渲染Image rendering

1.文字渲染的简单理解 渲染图像,可以理解为用cpu/gpu构造出原本不存在的图像。比如输入计算机的英文字符都是ASCII码,而我们在屏幕上看到显示的字符对应的应该是RGB/YUV的像素。计算机把ASCII字符转化成像素的过程就是文字渲染。又比如我们GPU用多个2D图…

Rust: 编译过程中链接器 `cc` 没有找到

这个错误信息表明在编译过程中链接器 cc 没有找到。cc 通常是 C 编译器的符号链接,它指向系统上的实际 C 编译器,如 gcc 或 clang。这个错误通常意味着你的系统缺少必要的编译工具链。 要解决这个问题,你需要确保你的系统上安装了 C 编译器。…

DolphinDB 携手九鞅科技,助力固收投研效能飞跃

随着金融市场开放的广度与深度不断拓宽,金融产品呈现出多样化的发展态势,其中债券投资组合凭借其低风险性、高流动性与稳健的收益表现,逐渐成为投资理财领域备受瞩目的焦点。投资经理不仅需要了解哪些债券值得投资,更要对债券投资…

neo4j、leafletjs、Cypher、celery、mysql去重、docker-compose doc

docker documentation leafletjs英文 leafletjs中文 python for neo4j第三方库neo4j Experience Neo4j on Your Desktop neo4j前端组件 neo4j中文文档(可能补全) Cypher 查询语法(中文) Deployment Center DELETE FROMtabl…

C++报错:没有与参数列表匹配的构造函数 (能确定类型是正确的)

原因: 构造函数定义的参数是“引用类型”,而你使用时,传入了临时变量 背景: 构造函数如下: Ray(Vector3d& p, Vector3d& d); 错误代码如下: Ray r1 Ray(Vector3d(0.0f,0.0f,3.0f) , Vector3…

web4.0-元宇宙虚拟现实

互联网一直在不断演变和改变我们的生活方式,从Web逐渐 1.0时代的静态网页到Web 2.0时代的社会性和内容制作,再从Web逐渐 在3.0阶段,互联网发展一直推动着大家时代的发展。如今,大家正站在互联网演化的新起点上,迈入Web…

Loongnix20.5系统ssh无法远程登陆问题

1. 确认客户端与服务器网络通信正常,能ping通。 2. 确认已启动ssh服务。 service ssh start后ssh登录正常。

微信hook协议3.84最新版

PC微信接口使用说明 用户故事 更新日志 登录与退出 获取进程端口占用信息 获取微信进程总数 启动微信 点击登陆微信 刷新并获取登录二维码 获取登录二维码数据(可以不调用) 获取微信登陆状态 退出微信 结束微信 个人信息管理 获取个人详细信息 保存收款码 获取本人地址 修改本人…

如何彻底搞懂装饰器(Decorator)设计模式?

对于任何一个软件系统而言,往现有对象中添加新功能是一种不可避免的实现场景,但这一实现过程对现有系统的影响可大可小。从架构设计上讲,我们也知道存在一个开闭原则(Open-Closed Principle,OCP)&#xff0…

android git提交代码命令以及常见命令的使用

安装Git Ubuntu: sudo apt-get install git-core创建代码仓库: 配置身份: git config --global user.name "Tony" git confit --global user.email "tonygmail.com"查看身份: git config --global user.…

【简单介绍下7-Zip,什么是7-Zip?】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

FFmpeg源码:#define IMAGEAUTO_DEMUXER(imgname, codecid) 宏定义分析

在FFmpeg源码(以5.0.3版本为例)目录下的libavformat/img2dec.c中存在如下宏定义 #define IMAGEAUTO_DEMUXER(imgname, codecid)\ const AVInputFormat ff_image_ ## imgname ## _pipe_demuxer {\.name AV_STRINGIFY(imgname) "_pipe&q…

C++语言学习(五)—— 类与对象(一)

目录 一、类类型的定义 二、类成员的访问控制 2.1 什么是"类内"和"类外" 2.2 对于访问控制属性的说明 三、类类型的使用 3.1 进行抽象 3.2 声明类 3.3 实现类 3.4 使用类 四、构造函数的引入 五、析构函数的引入 六、重载构造函数的引入 6.1 …