Java TDD简介–第1部分

欢迎来到测试驱动开发 (TDD)系列的介绍。 我们将在TDD上下文中讨论Java和JUnit ,但这只是工具。 本文的主要目的是使您全面了解TDD,而无论使用哪种编程语言和测试框架。

如果您在项目中不使用TDD,那么您要么很懒,要么就是根本不知道TDD的工作方式。 关于缺乏时间的借口不适用于这里。

关于这篇文章

在这篇文章中,我将解释什么是TDD以及如何在Java中使用它。 在TDD中,单元测试应放在哪个位置。 单元测试必须涵盖的内容。 最后,为了编写良好而有效的单元测试,需要遵循哪些原则。

如果您已经了解Java中有关TDD的所有知识,但是对示例和教程感兴趣,那么我建议您跳过这一部分,继续下一部分(它将在这一部分发布后的一周内发布)。

什么是TDD?

如果有人要我用几句话来解释TDD,那么我说TDD是功能实现之前的测试开发。 您可以争辩:很难测试尚不存在的事物。 肯特·贝克(Kent Beck)可能会为此一巴掌。

那怎么可能呢? 可以通过以下步骤进行描述:

1.阅读并了解特定功能的要求。
2.您开发了一组测试功能的测试。 由于没有功能实施,所有测试均为红色。
3.开发功能,直到所有测试变为绿色。 4.重构代码。

BDD流

TDD需要不同的思维方式,因此,为了根据它开始工作,您需要忘记以前开发代码的方式。 这个过程很难。 如果您不知道如何编写单元测试,那就更难了。 但这是值得的。

使用TDD进行开发具有宝贵的优势:

1.您对实现的功能有更好的了解。
2.您具有功能完整性的可靠指标。
3.代码包含测试,并且被修复或新功能破坏的可能性较小。

这些优势的代价是很高的–与切换到新的开发方式有关的不便以及您花费在开发每个新功能上的时间。 这是质量的代价。

这就是TDD的工作方式–编写红色的单元测试,开始实现功能,使测试变为绿色,执行代码重构。

TDD中单元测试的位置

由于单元测试是测试自动化金字塔中最小的元素,因此TDD基于它们。 借助单元测试,我们可以检查任何类的业务逻辑。 如果您知道如何做,则编写单元测试很容易。 那么,您需要使用单元测试进行测试的内容以及该怎么做呢? 您知道这些问题的答案吗? 我将尝试以简洁的形式说明答案。

吡酰胺单元测试的地方

单元测试应尽可能小。 不,不不要考虑这一点,因为一项测试仅适用于一种方法。 当然,这种情况也是可能的。 但通常,一个单元测试意味着调用多种方法。 这称为行为测试。

让我们考虑Account类:

public class Account {private String id = RandomStringUtils.randomAlphanumeric(6);private boolean status;private String zone;private BigDecimal amount;public Account() {status = true;zone = Zone.ZONE_1.name();amount = createBigDecimal(0.00);}public Account(boolean status, Zone zone, double amount) {this.status = status;this.zone = zone.name();this.amount = createBigDecimal(amount);}public enum Zone {ZONE_1, ZONE_2, ZONE_3}public static BigDecimal createBigDecimal(double total) {return new BigDecimal(total).setScale(2, BigDecimal.ROUND_HALF_UP);}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("id: ").append(getId()).append("\nstatus: ").append(getStatus()).append("\nzone: ").append(getZone()).append("\namount: ").append(getAmount());return sb.toString();}public String getId() {return id;}public boolean getStatus() {return status;}public void setStatus(boolean status) {this.status = status;}public String getZone() {return zone;}public void setZone(String zone) {this.zone = zone;}public BigDecimal getAmount() {return amount;}public void setAmount(BigDecimal amount) {if (amount.signum() < 0)throw new IllegalArgumentException("The amount does not accept negative values");this.amount = amount;}
}

该类中有4种getter方法。 要特别注意它们。 如果我们为每个getter方法创建一个单独的单元测试,则会得到太多的冗余代码行。 可以通过行为测试来处理这种情况。 想象一下,我们需要使用其构造函数之一来测试对象创建的正确性。 如何检查对象是否按预期创建? 我们需要检查每个字段的值。 因此,可以在这种情况下使用吸气剂。

创建小型快速的单元测试 ,因为它们应在每次提交到git存储库并将新的构建提交到服务器之前执行。 您可以考虑一个带有实数的示例,以了解单元测试速度的重要性。 假设一个项目有1000个单元测试。 他们每个人都需要100毫秒。 结果,所有测试的运行需要1分40秒。

实际上100ms对于单元测试来说太长了,因此您必须通过应用不同的规则和技术来减少运行时间,例如,不要在单元测试中执行数据库连接(根据定义,单元测试是隔离的)或在其中执行昂贵的对象的初始化。 @Before块。

为单元测试选择好名字 。 测试的名称可以是您想要的任何名称,但是它应该代表测试进行的验证。 例如,如果我需要测试Account类的默认构造函数,则将其命名为defaultConstructorTest 。 选择测试名称的另一个有用建议是在命名测试之前编写测试逻辑。 在开发测试时,您会了解其中发生的情况,因此名称的组成变得更加容易。

单元测试应该是可预测的 。 这是最明显的要求。 我将在示例中进行解释。 为了检查转帐操作(需支付5%的费用),您必须知道发送的金额以及输出的金额。 此测试方案可以实现为发送100美元和接收95美元。

最后应该对单元测试进行细化 。 在每个测试中放置一个逻辑场景时,您可以从测试中获得有用的反馈。 并且在发生单个故障的情况下,您不会丢失有关其余功能的信息。

单元测试原理

所有这些建议旨在改进单元测试设计。 但是,您还需要了解一件事-测试设计技术的基础知识。

测试设计技术基础

没有测试数据就不可能编写测试。 例如,当您测试汇款系统时,可以在汇款字段中设置一些金额。 在这种情况下,数量是测试数据。 那么您应该选择哪些值进行测试? 为了回答这个问题,我们需要经历最流行的测试设计技术。 测试设计技术的通用目的是简化测试数据的构成。

首先,让我们假设我们可以发送正整数的钱。 同样,我们发送的邮件不能超过1000。这可以表示为:

0 < amount <= 1000; amount in integer

我们所有的测试场景可以分为两组:正面和负面场景。 第一个用于系统允许的测试数据,并导致成功的结果。 第二种是所谓的“故障场景”,当我们使用不适当的数据与系统进行交互时。

根据等价技术类别,我们可以从(0; 1000]范围内选择一个随机整数。设为500。由于系统适用于500,因此对于该范围内的所有整数均适用。有效值,也可以从范围中选择无效的输入,可以是任何带浮点的数字,例如125.50

然后我们必须参考边界测试技术 。 根据它,我们必须从范围的左侧和右侧选择2个有效值。 在我们的例子中,我们以1为允许的最小正整数,从右边取1000。
下一步是在边界上选择2个无效值。 所以它是0和1001

因此,最后我们有6个值需要在单元测试中使用:

  • (1,500,1000)–对于积极的情况
  • (0,125.50,1001)–否定情况

摘要

在这篇文章中,我试图解释TDD的各个方面,并说明在TDD中单元测试的重要性。 因此,我希望经过如此详尽和长期的bla-bla理论,我们可以继续实践。 在下一篇文章中,我将演示如何在功能之前开发测试。 我们将从文档分析开始,到代码重构结束,逐步进行操作。

确保所有测试都是绿色的:)

翻译自: https://www.javacodegeeks.com/2015/11/introduction-in-java-tdd-part-1.html

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

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

相关文章

状态模式 处理订单状态_将状态机模式实现为流处理器

状态模式 处理订单状态在我的上一个博客中&#xff0c;我说过我真的以为某些“四人行”&#xff08;GOF&#xff09;模式已经过时了&#xff0c;如果不是过时的话肯定不受欢迎。 特别是我说过StateMachine没什么用&#xff0c;因为您通常会想到另一种更简单的方式来执行您正在执…

mysql 连续签到天数_最大连续签到天数-sql

SELECT MIN(rq) as 起始日期, MAX(rq) as 终止日期, MAX(id1) - MIN(id1) 1 as 持续天数,id3 as 累计签到天数,nameFROM (SELECT datediff(rq,2020-02-01 )id1, (SELECT COUNT(1)FROM tmptableWHERE rq < a.rq andtype 是) id2,(SELECT COUNT(1)FROM tmptableWHEREtype 是…

mysql 两个查询结果合并去重_《MySQL 入门教程》第 21 篇 集合操作符

文章来源&#xff1a;https://blog.csdn.net/horses/article/details/108174837来源平台&#xff1a;CSDN原文作者&#xff1a;不剪发的Tony老师数据表与集合理论中的集合非常类似&#xff0c;表是由行组成的集合。SQL 标准定义了基于行的各种集合操作&#xff1a;并集运算(UNI…

binutils工具集之---ar

1.如果要将多个.o文件生成一个库文件&#xff0c;则存在两种类型的库&#xff0c;一种是静态库&#xff0c;在linux里面后缀是.a&#xff0c;另一种是动态库&#xff0c;后缀为.so。 当可执行程序要与静态库进行链接时&#xff0c;所用到的库中的函数和数据会被拷贝到最终的可执…

jax-rs jax-ws_Google App Engine JAX-RS REST服务

jax-rs jax-ws在本文中&#xff0c;您将学习如何使用JAX-RS参考实现&#xff08;Jersey&#xff09;创建REST服务并将其部署在Google AppEngine上。 先决条件 对于本教程&#xff0c;您将需要&#xff1a; 一个Google AppEngine帐户 Eclipse Galileo&#xff08;3.5.x&#xf…

[转]使用C#开发ActiveX控件

前言 ActiveX控件以前也叫做OLE控件&#xff0c;它是微软IE支持的一种软件组件或对象&#xff0c;可以将其插入到Web页面中&#xff0c;实现在浏览器端执行动态程序功能&#xff0c;以增强浏览器端的动态处理能力。通常ActiveX控件都是用C或VB语言开发&#xff0c;本文介绍另一…

用Java测试多线程代码

测试多线程代码是一个艰巨的挑战。 尝试测试并发性时获得的第一个建议是尽可能地在代码中隔离并发问题。 这是一般的设计建议&#xff0c;但在这种情况下甚至更重要。 确保首先正确地对并发构造所包装的逻辑进行单元测试。 否则&#xff0c;您可能会花费很长时间尝试找出一个并…

php pdo mysql query_PHP+MYSQL中使用PDO的query方法

一 代码class"php">PDO连接MySQL数据库IDPDO数据库时间$dbmsmysql; //数据库类型 ,对于开发者来说&#xff0c;使用不同的数据库&#xff0c;只要改这个&#xff0c;不用记住那么多的函数$hostlocalhost; //数据库主机名$dbNamedb_database15; //使用的数据库$use…

java 冒号 正则表达式_Java正则表达式问号冒号的使用

在Java和Javascript中正则表达式字符串前面加上?:表示非捕获型匹配&#xff0c;否则就是捕获型匹配。捕获型括号会将匹配到的内容捕获到一些变量里&#xff0c;这些变量按照捕获型括号的左括号为顺序从1开始编号。为了避免括号太多使编号混乱&#xff0c;也为了避免无用的捕获…

Hibernate中的一对多XML映射

一对多关系指出一个实体的单个实例与另一个实体的多个实例相关联。 换句话说&#xff0c;一个表中的每个记录与另一个表中的多个记录相关联。 让我们看看如何通过XML映射文件在Hibernate中定义这种关系。 1.实体关系图 假设我们已经在数据库中创建了学生表和部门表&#xff0…

camel eip_Apache Camel教程– EIP,路由,组件,测试和其他概念的简介

camel eip公司之间的数据交换增加了很多。 必须集成的应用程序数量也增加了。 这些接口使用不同的技术&#xff0c;协议和数据格式。 但是&#xff0c;这些应用程序的集成应以标准化的方式建模&#xff0c;有效实现并由自动测试支持。 企业集成模式&#xff08;EIP&#xff09;…

JavaOne和OOW 2015总结

大家好&#xff01; 终于&#xff0c;我回来了一个很棒的JavaOne和OOW2015。在这篇文章中&#xff0c;我想分享我的经验&#xff0c;一些照片和我参加的演讲的摘要。 会议前 我于2015年6月24日星期六乘Copa航空公司CLO-PTY-SFO飞往旧金山。 从哥伦比亚出发&#xff08;大约8小…

Marin说PCB之 PCB封装和原理图封装的藕断丝连--续集(2)

最近天气越来越冷了&#xff0c;小编我在上海漂泊的十多年了&#xff0c;感觉今年似乎是最冷的一年啊。家里的秋裤都不管用了&#xff0c;要换成大棉裤和军大衣啊。而且现在羽绒服大部分都很贵&#xff0c;动不动上千元了&#xff0c;都赶得上小编我几个月的私房钱了都&#xf…

调整线程池的重要性

无论您是否知道&#xff0c;您的Java Web应用程序很可能都使用线程池来处理传入的请求。 这是许多人忽略的实现细节&#xff0c;但是迟早您需要了解如何使用该池以及如何为您的应用程序正确调整池。 本文旨在说明线程模型&#xff0c;什么是线程池以及正确配置线程池所需执行的…

在线原理图绘制网站推荐

如今专业EDA软件已经基本在硬件公司普及并正版化&#xff0c;优秀的EDA工具包括 Cadence公司的OrCAD、Allegro软件&#xff0c;Mentor Graphics的PADS&#xff0c; Altium公司的Altium Designer等等&#xff0c;但是它们在功能异常强大的同时也在一些时候显得非常复杂&#xff…

java map与set的区别_java 集合(list,set,map)三者之间的关系和区别

原java 集合(list&#xff0c;set&#xff0c;map)三者之间的关系和区别一&#xff1a;先上一张关系图&#xff0c;让大家看的更明白。备注&#xff1a;其中红色部分为实现&#xff0c;其他地方均为接口。二&#xff1a;各自的特点。List 有序,可重复ArrayList优点: 底层数据结…

adf时间作用域_ADF任务流:页面片段的托管bean作用域

adf时间作用域介绍 当我们使用ADF任务流并需要实现一些特定于流的业务逻辑或存储一些与流相关的信息时&#xff0c;我们通常使用pageFlowScope托管bean。 而且&#xff0c;当我们需要为流的活动&#xff08;页面或页面片段&#xff09;提供服务时&#xff0c;我们会为此类托管b…

IMA文件如何打开,winimage使用方

一般先用UltraISO打开一个系统的镜像文件&#xff08;.iso&#xff09;。其中有些文件&#xff08;尤其是.ima,img&#xff09;比如下面雨林木风Ghost系统盘的这个IMA文件&#xff0c;我们先提取到桌面 用WinImage打开这个文件即可发现这个IMA文件整合了很多东西。所以&#x…

Java的几何布朗运动

Wiener过程是连续时间随机过程&#xff0c;以纪念Norbert Wiener命名。 通常用于用随机成分表示噪音或财务状况。 可以计算几何布朗运动以可视化某些界限&#xff08;以分位数表示&#xff09;以暗示绝对范围。 为了进行计算&#xff0c;需要以下参数&#xff1a; &#xff0…

mongodb java id 查询数据_java 用 _id 查找 MongoDB 下的数据

找网上的资料看了下增删改查&#xff0c;等日后补上。已经实现了数据的插入&#xff0c;现在想通过 _id属性来查找数据。一开始看到 类似 55b321df715cc162076eb466 这么一长串的内容觉得是string类型。但是发现并不能搜索到结果&#xff0c;在网上搜到了解决方案&#xff1a;S…