tdd 单元测试

最近,我一直在写与自动测试有关的更高级的概念(主要与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/小Cucumber编写的用于验收测试的方案)或以自由形式(例如,特别注意的要点或只是下一步应该做什么的想法)来完成。 有了这些知识,就很容易确定整个测试将组成的三个关键部分(分开的部分)。

给定–准备

在单元测试的第一部分(称为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是一个更广泛的概念,它对于编写具有预先定义的需求(通常是非技术形式)的功能/验收测试特别方便。 一种替代的测试划分语法(对于各节而言,含义非常相似)是“ 配置行为声明”,通常缩写为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 单元测试

tdd 单元测试_何时给定在单元测试和TDD中的重要性相关推荐

  1. @sql 单元测试_如何在SQL单元测试中使用假表?

    @sql 单元测试 In this article on SQL unit testing, we will talk about how to isolate SQL unit tests from ...

  2. ju 单元测试_使用 JUnit4 编写单元测试

    主要内容: 从 What, Why, When, How, Deep 几个方面来介绍单元测试相关的基础知识. 需要技能: 了解 Java 编程语言,能够使用 IDEA 等. What 单元测试(uni ...

  3. python 单元测试_聊聊 Python 的单元测试框架(一):unittest

    本文首发于 HelloGitHub 公众号,并发表于 Prodesire 博客. 前言 说到 Python 的单元测试框架,想必接触过 Python 的朋友脑袋里第一个想到的就是 unittest. ...

  4. 如何准备机器学习数据集_数据准备技术及其在机器学习中的重要性

    如何准备机器学习数据集 什么是数据? (What is Data?) Data refers to examples of cases from the domain that characteriz ...

  5. dataframe 拼接_拼接关系图在石材生产过程中的重要性

    石材生产加工中应用许多图,石材纹理图.平面面置图.平面图.立面图.剖面图,这些图对石材生产加工都有很大的帮助,发挥着各自的作用,担负着各自的角色.除了这些图外,石材生产加工中还有一种图-拼接关系图,表 ...

  6. 单元测试编写_编写详尽的单元测试

    单元测试编写 As software developers we all know how important it is to unit test the code that we write. S ...

  7. go 清空文件内容_玩转Go单元测试,你只需要掌握这5点

    最近在给项目代码完善单元测试,发现go语言单元测试相关的资料都是零零散散的,所以在这儿整理总结一下.项目中使用的是goconvey+monkey+sqlmock (项目的web框架为gin, 持久层框 ...

  8. php带参数单元测试_一文搞定单元测试核心概念

    基础概念 单元测试(unittesting),是指对软件中的最小可测试单元进行检查和验证,这里的最小可测试单元通常是指函数或者类.单元测试是即所谓的白盒测试,一般由开发人员负责测试,因为开发人员知道被 ...

  9. java 单元测试_在springboot中写单元测试解决依赖注入和执行后事务回滚问题

    往期文章 「Java并发编程」谈谈Java中的内存模型JMM 面试官:说说你知道多少种线程池拒绝策略 为什么不要在MySQL中使用UTF-8编码方式 前言 很多公司都有写单元测试的硬性要求,在提交代码 ...

最新文章

  1. OpenCV3编程入门(毛星云)之视频读取与播放
  2. YbtOJ-交换游戏【树链剖分,线段树合并】
  3. linux 查看tdagent进程,Zabbix监控记录linux服务器近期的登录情况
  4. Hirens Boot DVD 15.2 功能恢复版 v1.1 -- 制作U盘启动盘
  5. MySQL06:变量、存储过程和函数、流程控制结构
  6. python函数定义及调用-Python函数及变量的定义和使用
  7. Python学习之购物车
  8. 优化理论02----凸函数、共轭函数、拟凸函数、对数凹/对数凸函数、关于广义不等关系的凸性
  9. html mysql查询_mysql查询
  10. 人力资源学python有意义吗-为什么每个HR都应该学习一点编程?
  11. 六子棋计算机博弈关键技术研究,六子棋计算机博弈系统的研究与实现-计算机应用技术专业论文.docx...
  12. 软件需求分析----实验室设备管理系统
  13. 【微信小程序】合法域名校验出错,不在以下合法域名列表中 解决方法
  14. C语言之i++,++i,i--,--i
  15. 重读《拿破仑传》有感
  16. 5款高效软件推荐,每一款都是良心之作
  17. JS事件之事件绑定与事件监听
  18. 山东标梵网站制作项目启动流程详解
  19. 从val_loss,train_loss,test_loss中产生的问题
  20. nvme固态必须uefi启动吗_戴尔Inspiron 灵越笔记本装win10系统及bios设置教程(uefi+gpt)...

热门文章

  1. [USACO19JAN,Platinum]Train Tracking 2
  2. P7046-「MCOI-03」诗韵【SAM,倍增,树状数组】
  3. 牛客-沙漠点列【tarjan】
  4. jzoj5231-序列问题【分治】
  5. ssl2124-涂色【离散化】
  6. ssl1761-城市问题【图论,最短路,Dijkstra】
  7. poj3648 Wedding 2-sat
  8. Spring经典面试题和答案
  9. 分布式 | Dubbo 架构设计详解
  10. Oracle入门(十四.12)之游标FOR循环