最近,我一直在写与自动测试有关的更高级的概念(主要与Spock有关)。 但是,在进行测试培训时,我清楚地看到,通常对特定工具的知识并不是主要问题。 即使使用Spock,也可以编写肿且难以维护的测试,从而破坏(或不了解)与编写单元测试有关的良好实践。 因此,我决定写一些更基本的东西来促进它们,并且在指导经验不足的同事时准备使用一些参考材料。

介绍

编写良好的单元测试应满足几个要求,这是整个系列的主题。 在这篇博客文章中,我想提出一个相当成熟的概念,即使用严格定义的功能(依次是行为驱动开发的子集)将单元测试划分为3个独立的块。

单元测试通常集中于测试给定单元(通常是一个给定类)的某些特定行为。 与通过UI执行的验收测试相反,在每个测试中都将存根/模拟作为其合作者,从零开始设置一个要测试的类(被测类)是便宜(快速)。 因此,性能应该不是问题。

样品测试

为了演示规则,我将使用一个小例子。 ShipDictionary是一个类,可根据特定条件(按名称的一部分,生产年份等)搜索太空船。 该词典由不同的船舶索引(在役,退役,在生产等中的船舶)提供动力。 在那个特定的测试中,它被测试了按其名称的一部分搜索飞船的能力。

private static final String ENTERPRISE_D = "USS Enterprise (NCC-1701-D)";@Test
public void shouldFindOwnShipByName() {
//given
ShipDatabase shipDatabase = new ShipDatabase(ownShipIndex, enemyShipIndex);
given(ownShipIndex.findByName("Enterprise")).willReturn(singletonList(ENTERPRISE_D));
//when
List foundShips = shipDatabase.findByName("Enterprise");
//then
assertThat(foundShips).contains(ENTERPRISE_D);
}

给定时间

测试驱动开发方法和行为驱动开发方法中都存在的良好习惯是“先验”知识,将在特定测试用例中进行测试(认定)。 可以以更正式的方式(例如,用Cucumber / Gherkin编写的用于验收测试的方案)或以自由形式(例如,特别注意的要点或只是下一步应该做什么的想法)来完成。 有了这些知识,就很容易确定整个测试将组成的三个关键部分(分开的部分)。

给定–准备

在单元测试的第一部分(称为given )中,需要创建一个实际对象实例,在该对象实例上将执行测试的操作。 在重点单元测试中,只有一类放置要测试的逻辑。 此外,应将执行测试所需的其他对象(称为协作者)初始化为存根/模拟,并适当存根(如果需要)。 还必须将所有协作者注入到要测试的对象中,该对象通常与对象创建结合在一起(因为构造函数注入应该是依赖注入的首选技术)。

//given
ShipDatabase shipDatabase = new ShipDatabase(ownShipIndex, enemyShipIndex);
given(ownShipIndex.findByName("Enterprise")).willReturn(singletonList(ENTERPRISE_D));

何时–执行

when部分中,将执行要测试的操作。 在我们的情况下,这是一个搜索请求,然后将结果存储在变量中以供进一步声明。

//when
List foundShips = shipDatabase.findByName("Enterprise");

在大多数情况下,在该部分中仅执行一个操作是一件好事。 更多的元素可能表明尝试测试多个操作(可能)可以分为多个测试。

然后–断言

-最后一节的责任, then -主要是先前接收到的结果的断言。 它应该等于期望值。

//then
assertThat(foundShips).contains(ENTERPRISE_D);

另外,可能有必要对声明的模拟执行方法执行的验证。 这不应该是一种普遍的做法,因为在大多数情况下,对接收值的声明足以确认所测试的代码按预期工作(根据设置的边界)。 但是,尤其是在测试void方法时,需要验证使用预期参数执行的特定方法。

AAA aka 3A –一种替代语法

正如我已经提到的,BDD是一个更广泛的概念,对于编写具有预先定义的需求(通常以非技术形式)的功能/验收测试而言,BDD特别方便。 一种替代的测试划分语法(对于各节而言具有非常相似的含义)是通常将其缩写为AAA或3A的“ 排列动作声明” 。 如果您根本不使用BDD,并且三个字母比GWT更容易记住,那么使用它来创建相同的高质量单元测试就很好。

调整与优化

将实用工具和方法学与持续进行的技能获取过程(也称为Dreyfus模型 )进行匹配的过程已在《 实用思维与学习:重构您的湿软件 》一书中进行了很好的描述。 当然,在许多情况下,使用测试的简化变体可能很方便, given节移到setup/init/before节或内联初始化。 同样可以适用于whenthen部分,其可以被合并在一起(成expect部分,特别是在参数化测试)。 具有编写单元测试的经验和流利性,使用速记和优化(特别是测试一些非平凡的案例)是完全有效的。 只要整个团队都了解约定,并且能够记住有关编写好的单元测试的基本假设。

摘要

根据我在软件开发方面的经验以及作为一名培训师,我清楚地看到将(单元)测试划分为多个部分可以使它们更短,更易读,尤其是团队中经验不足的人员。 用简单定义的责任来填充3个部分比立即找出并在测试中编写所有内容要容易得多。 最后,特别是对于仅阅读本文第一部分和最后部分的人们,此处遵循以下简明规则:

  • given –测试中的对象初始化+存根/模拟的创建,存根和注入
  • when –在给定测试中进行测试的操作
  • then –收到结果声明+模拟验证(如果需要)

PS最好在IDE中设置一个测试模板,以保护编写每个测试所需的许多击键。
PSS,我认为本文很有用,您可以让我知道,以激励我将来写更多有关单元测试的基础知识。

图片来源:Tomas Sobek,Openclipart, https ://openclipart.org/detail/242959/old-scroll

自我提升 。 您想快速有效地提高您和您的团队的测试技能以及对Spock / JUnit / Mockito / AssertJ的了解吗? 我进行了浓缩(单元) 测试培训 ,您可能会觉得有用。

翻译自: https://www.javacodegeeks.com/2017/05/importance-given-unit-tests-tdd.html

在单元测试和TDD中指定时间的重要性相关推荐

  1. 软件开发重要性_在软件开发中考虑时间的重要性

    软件开发重要性 by Crunch Tech 通过Crunch Tech 在软件开发中考虑时间的重要性 (The importance of time to think in Software Dev ...

  2. tdd 单元测试_何时给定在单元测试和TDD中的重要性

    tdd 单元测试 最近,我一直在写与自动测试有关的更高级的概念(主要与Spock有关). 但是,在进行测试培训时,我清楚地看到,通常对特定工具的知识并不是主要问题. 即使使用Spock,也可以编写肿且 ...

  3. linux查找某时间后的关键字,linux - 查找指定时间的文件及文件中的关键字

    Linux查找某个时间内的文件 1.? n天内修改的(-ctime) find . -type f -ctime -1| xargs ls –l 说明: (1) -type f 只搜索文件,不包含文件 ...

  4. java中获取指定时间的时间戳

    在 Java 中,可以使用 Instant 类来获取指定时间的时间戳. 首先,你需要使用 ZonedDateTime 类来表示指定的时间.你可以使用 ZonedDateTime.of 方法来创建一个 ...

  5. mysql 分钟_MySQL如何获取一个指定时间中的分钟数(MINUTE函数)呢?

    摘要: 下文讲述MySQL数据库中获取指定时间数据中的分钟数的方法分享,如下所示: 实现思路: 使用MINUTE(time)系统函数即可返回日期中的分钟信息 MINUTE系统函数语法说明: MINUT ...

  6. 365天挑战LeetCode1000题——Day 038 公交站间的距离 + 基于时间的键值存储 + 转变数组后最接近目标值的数组和 + 有界数组中指定下标处的最大值

    文章目录 1184. 公交站间的距离 代码实现(自解) 981. 基于时间的键值存储 代码实现(自解) 1300. 转变数组后最接近目标值的数组和 代码实现(自解) 1802. 有界数组中指定下标处的 ...

  7. Java中时间格式化(获取指定时间)

    Java中时间格式化(获取指定时间,七天前) 1.通过获取当前系统时间,格式化后转为"yyyy-MM-dd HH:mm:ss"格式并输出: 2.可获取指定时间,如七天前,一年前等, ...

  8. html中wmv播放不要自动播放,网页播放器 windowsmediaplay中控制从wmv的指定时间开始播放,指定时间停止播放...

    首页 > 网络编程 > 网页播放器 > 网页播放器 windowsmediaplay 网页播放器 windowsmediaplay中控制从wmv的指定时间开始播放,指定时间停止播放 ...

  9. Java 中验证时间格式的 4 种方法

    大家好,今天咱们来讲一下,Java 中如何检查一个字符串是否是合法的日期格式? 为什么要检查时间格式? 后端接口在接收数据的时候,都需要进行检查.检查全部通过后,才能够执行业务逻辑.对于时间格式,我们 ...

最新文章

  1. iOS - 毛玻璃动画效果
  2. 1.1.12 增加页眉横线
  3. 【批处理】windows环境将文件放置在虚拟盘
  4. socket编程简单Demo讲解及源码分享(C# Winform 内网)
  5. Netty工作笔记0012---Channel应用案例3
  6. 基于流程的多维度企业管理框架(第三稿)
  7. 文本生成系列之transformer结构扩展(一)
  8. Java实现国密算法SM2,SM3,SM4,并且实现ECB和CBC模式
  9. 江在川上曰:webpack前端工程化
  10. STL — 迭代器设计思维(一)
  11. PHP设计模式之适配器模式(Adapter)了解下
  12. 迅速提高代码编写速度的训练方法
  13. kali2020之快速搜索文件工具——安装篇
  14. vector sort 出现异常处理--std::sort(_RanIt,_RanIt,_Pr)
  15. 推荐系统模型论文阅读笔记
  16. Github神项目推荐:深度神经网络修复打码H漫
  17. 大数据-智慧城市解决方案
  18. 精灵图为什么叫雪碧图(精灵图的历史)
  19. 自动化测试的PO模式
  20. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三)

热门文章

  1. JavaFX UI控件教程(十六)之Separator
  2. 一道非常棘手的 Java 面试题:i++ 是线程安全的吗
  3. 对于自绝对父相的理解
  4. 用数组存储字符C进行回文检测
  5. 注意!在subList生成子列表之后,一定不要随便更改原列表
  6. sql server中创建数据库和表的语法
  7. java实现人脸识别源码【含测试效果图】——DaoImpl层(BaseDaoUtilImpl)
  8. 消费端整合SpringCloudGateway
  9. 把本地文件上传到gitee
  10. 35 岁程序员的独家面试经历