正确设置JUnit测试名称

寻找好名字是手工软件的挑战之一。 您需要随时随地找到它们-类,方法,变量,仅举几例。 但是,什么使名字成为好名字呢? 引用Oncle Bob的话:“三件事:可读性,可读性和可读性!” 他后来通过表达的清晰,简单和密度1对其进行了定义

尽管这对我来说很有意义,但是我发现自己尤其在测试方法方面有些挣扎。 为了更好地理解我在说什么,需要知道我编写了代码测试驱动程序 。 做了一段时间之后,我逐渐将工作重点从被测单元转移到了测试本身。 这可能是因为我喜欢将一个测试用例视为一个完整的规范和质量保证,因此它非常重要2

因此,只要测试失败,理想情况下,我就能一眼就能知道哪个规范被破坏以及为什么。 实现此目的的最佳方法似乎是找到一个表达性的测试名称,因为这是报告视图中显示的第一条信息:

规格

从这个角度来看,我并不总是对这种观点所显示的内容感到满意,因此我花了一些时间进行研究,以了解哪些思想流派可能会有所帮助。 不幸的是,我发现的大多数结果都有些过时,并且-不足为奇-关于该主题的意见分歧。 这篇文章基于这些发现和一些个人经验,代表了我的看法。

根据方法或行为测试名称进行测试?

每种方法的测试形式通常都是由工具提供的,例如,在事后生成单个测试存根。 如果您的类Foo带有方法bar则生成的方法将称为testBar 。 我一直对这种开发风格或命名约定的有用性持怀疑态度,并且会像旧的JavaRanch线程中的引文一样争论:“您根本不应该将其视为测试方法,而应该将其视为测试行为。班上的 因此,我喜欢我的测试方法名称来传达预期的行为3

有趣的是,我将对那一点改变看法。 如上所述,传达“行为”的想法要求找到一个简明的名称来全面表达该“行为”。 但是随后,术语行为表示由一个动作从一个状态过渡到另一种状态,或者用BDD术语表示,例如“时给定”模式。 老实说,我认为将所有这些信息放在一个单一的名字中通常不是一个好主意4

@Test
public voidgivenIsVisibleAndEnabledWhenClickThenListenerIsNotified() {}
@Test
public voidgivenIsVisibleAndNotEnabledWhenClickThenListenerIsNotNotified() {}
@Test
public voidgivenIsNotVisibleAndEnabledWhenClickThenListenerIsNotNotified() {}

也许这只是一个口味问题,但是根据我的经验,无论我选择哪种格式样式,由于缺乏简单性和/或清晰度,这种方法通常缺乏可读性。 此外,这样的重载名称往往与注释具有相同的问题–随着内容的发展,这些名称很容易过时。 因此,我想改用BUILD-OPERATE-CHECK 5模式。 这将允许将阶段拆分为单独的子方法名称,并将其放置在单个测试中:

@Test
public void testNameHasStillToBeFound() {// do what is needed to match preconditiongivenIsVisibleAndEnabled();// execute the transitionwhenClick();// verify the expected outcomethenListenerIsNotified();
}

不幸的是,这导致我们进入了起点。 但是,如果仔细看一下上面的示例,所有方法都围绕着一个共同的分母。 它们都属于触发转换的同一动作。 在我们的例子中,点击事件。 考虑到从开发过程的角度来看,我认为一个测试用例比被测试的单元更为重要,因此可以将其解释为一种符号,以在开发中的单元中以适当的方法名称来反映操作6

因此,出于示例的考虑,假设我们有一个环绕UI控件的ClickAction 。 鉴于上述情况,引入一种称为ClickAction#execute()的方法对我们来说似乎很合适。 为简单起见,我们可以将该名称也用于表示从ClickAction默认状态到通过ClickAction#execute()控件构造的转换的测试方法:

class ClickActionTest {@Testpublic void execute() {Control control = mock( Control.class );ClickAction clickAction = new ClickAction( control );clickAction.execute();verify( control ).notifyListeners(...)}
}

为了简单起见,下一个测试名称可能只提及重要的状态信息,因为它不同于默认值并导致另一个结果:

class ClickActionTest {[...]@Testpublic void executeOnDisabledControl() {Control control = mock( Control.class );when( control.isEnabled() ).thenReturn( false );ClickAction clickAction = new ClickAction( control );clickAction.execute();verify( control, never() ).notifyListeners(...)}@Testpublic void executeOnInvisibleControl() {[...]
}

如您所见,这种方法产生了一组测试名称,从技术上讲,它们代表各种“每种方法的测试”模式-但并非出于我认为完全出于不利的原因。 考虑到上下文,我认为这种命名模式很简单,清晰并且可以表达:

仍未提及预期的测试结果。 乍一看,这似乎并不令人满意,但是从我目前的观点来看,我愿意接受这一点,这是一种合理的权衡。 尤其是在JUnit报告视图中通常还会显示测试失败的原因。 因此,可以通过提供有意义的测试失败7来解决该问题。

结论

实际上,我一段时间以来正在使用上述测试命名模式。 到目前为止,效果还不错。 特别是在像我通常使用的非常小的单元上工作时,几乎没有错误解释的空间。 但是,这种方法并不适合所有情况,有时候感觉更好,并且可读性足以提及结果。 我不会在这里谈论原则,也许我弄错了。 因此,对于任何您可能会意识到可以扩大我的观点的更详细方法的指示,我都会感到高兴。

  1. Robert C. Martin关于清洁测试,清洁代码,第9章单元测试↩
  2. 更糟的是:丢失被测单元或测试用例? 使用良好的测试用例,在大多数情况下,恢复单元应该很容易,但是反之亦然,您很容易错过丢失的测试用例中指定的其中一个极端用例↩
  3. 使用JUnit的方法的命名约定,使用JUnit的方法的命名约定 ↩
  4. 为避免误解: BDD并没有提供类似的功能,并且具有自己的测试框架。 我只是在这里提到它,因为“行为”一词似乎暗示了这一点,而“ givenWhenThen”一词在有关测试名称的许多讨论中不胜枚举。 然而,你居然发现像罗伊Osherove的命名约定标记建议“UnitOfWork_StateUnderTest_ExpectedBehavior”这似乎仍然被广泛接受虽然帖子已经看到大多数的最后十年的日子↩
  5. Robert C. Martin,《清洁规范》,第9章,清洁测试↩
  6. 甚至将全部功能提取到一个单独的类中。 但是,这种情况下,在我的岗位描述更具有MoreUnit单位 ↩
  7. 这可能是一个主题,当我不得不结束时,我就这样保留它! ↩

翻译自: https://www.javacodegeeks.com/2014/03/getting-junit-test-names-right.html

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

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

相关文章

angular学习的一些小笔记(中)之ng-disabled轻松实现按钮是否可点击状态

哇&#xff0c;这个可以轻松实现输入值就按钮可点击&#xff0c;输入框没有值则不可点击的状态呀 看代码 <!doctype html> <html ng-app""> <head><script src"https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js&q…

html5储存类型特点,避免踩雷!你不得不知的 HTML5 “新”特性

什么是 HTML5HTML的发展历程如下&#xff1a;产生于1990年1997年 HTML4 出现&#xff0c;成为互联网开发的标准2008年&#xff0c;HTML5正式出现&#xff0c;2002年趋于稳定HTML在发展过程中&#xff0c;HTML4.01 版本维持了长达十年的时间&#xff0c;之后 HTML5 标准才出现&a…

How to show out three rows from the same databand On A4?

How to show out three rows from the same databand On A4? QuotePost by DoraHuang Tue Mar 13, 2018 4:13 am Hello, there are few questions to ask,1. How to present a report from one DataBand to show out three info?My questions like the picture:it is A4 pag…

rds基于什么开发_IaaS、PaaS、SaaS、DaaS都是什么?现在怎么样了?终于有人讲明白了...

导读&#xff1a;本文将详细科普云计算的概念、云服务的发展现状&#xff0c;并逐一介绍各种云服务模式&#xff08;IaaS、PaaS、SaaS、DaaS&#xff09;&#xff0c;建议收藏&#xff01;01 云计算的概念云是一种服务&#xff0c;可以像使用水、电、煤那样按需使用、灵活付费&…

30岁前不要在乎的29件事(转载)

30岁前不要在乎的29件事(转载) 作者&#xff1a; 2004-2-13 20:08:22 原始出处&am…

[转]css实现左侧宽度自适应,右侧固定宽度

原文地址:https://segmentfault.com/a/1190000008411418 页面布局中经常用会遇到左侧宽度自适应&#xff0c;右侧固定宽度&#xff0c;或者左侧宽度固定&#xff0c;右侧自适应。总之就是一边固定宽度&#xff0c;一边自适应宽度。 一般固定宽度是导航栏&#xff0c;自适应宽度…

Java 8发布了! — Lambdas教程

为了庆祝几分钟前发布的Java 8的发布&#xff0c;我正在发布Java 8 Lambdas教程的草稿版本。 这是学习Streams API的一种很好的可视化方法&#xff0c;从第一天开始&#xff0c;它将帮助您开始在自己的应用程序中利用lambda。本文计划在下一期Java Magazine发行中发表&#xff…

angular学习的一些小笔记(中)之表单验证

表单验证 我去&#xff0c;我感觉我这个人其实还是一个很傻逼的一个人&#xff0c;老是因为拼错了一个单词或者怎么样就浪费我很长时间&#xff0c;这样真的不行不行&#xff0c;要正确对待这个问题&#xff0c;好了&#xff0c;说正题吧&#xff0c;angular也有表单验证minle…

html 表单优化,用CSS3优化HTML5表单的步奏

今天给大家带来用CSS3来优化HTML5表单的方法&#xff0c;首先我们创建一个表单&#xff0c;格式如下。#redemption {width: 100%;font-family: ColaborateThinRegular;font-weight: 400;}#redemption hgroup {argin-bottom: 20px;}#redemption div {width: 100%;margin-bottom:…

redis 学习(18)-- AOF

redis -- AOF 什么是 AOF 通过日志方式将redis中的写命令进行日志记录&#xff0c;保存在硬盘文件中。 日志记录的实质是将写命令写在硬盘的缓冲区中&#xff0c;再根据相关策略把数据刷新到磁盘中。 当redis服务器启动时候&#xff0c;执行硬盘中的日志文件以恢复redis中的数据…

重启IIS和SqlServer的命令行

在WEB开发中经常需要重启IIS,每次打开IIS来操作很麻烦&#xff0c;所以我干脆就在桌面新增了一个CMD文件&#xff0c;内容如下&#xff1a;&#xff08;SQL Server占的内存不少&#xff09;net stop iisadmin /ynet start w3svc net stop mssqlservernet start mssqlserver每次…

精简SWT FormLayout的用法

出于对效率的追求&#xff0c;我最近重新考虑了SWT FormLayout的可用性。 尽管就灵活性而言&#xff0c;它是我最喜欢的核心布局之一&#xff0c;但我不得不认识到&#xff0c;大多数同事都不情愿地使用它。 考虑到面部反应&#xff0c;建议将其建议用于适当的任务有时实际上会…

vue 启动时卡死_十分钟浅入Vue 原理

vue原理引用众所周知vue是一个MVVM 渐进式框架&#xff0c;MVVM是vue的设计模式&#xff0c;在vue框架中数据会自动驱动视图。1、MVVM设计模式 ​ 解释View是视图&#xff0c;就是DOM&#xff1b;对应视图也就是HTML部分--代表UI组件&#xff0c;它负责将数据模型转化成UI展现出…

可以使用计算机解决的问题是什么,1.1 使用计算机解决问题的一般过程教案1

算法及其实现【学习目标】1、了解算法的含义2、了解算法的表示方法3、会用流程图表示算法4、能正确理解流程图中算法的意义【重难点】正确理解流程图中算法的意义【问题引导】问&#xff1a;在考试练习中&#xff0c;同学们一定遇到这种题&#xff0c;你们怎么来做&#xff1f;…

centos7.3 安装 mysql-5.7.13

系统环境: [rootlocalhost ~]# cat /etc/RedHat-release CentOS release 6.7 (Final)[rootlocalhost tools]# uname -aLinux localhost 2.6.32-573.22.1.el6.x86_64 #1 SMP Wed Mar 23 03:35:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux[rootlocalhost tools]# 软件准备:[root…

GARFIELD@12-20-2004

克已复礼为仁转载于:https://www.cnblogs.com/rexhost/archive/2004/12/20/79502.html

Java 8的功能基础

Java 8彻底改变了Java。 它很可能是过去10年中最重要的Java版本。 有很多新功能&#xff0c;包括默认方法&#xff0c;方法和构造函数引用以及lambda&#xff0c; 仅举几例 。 更有趣的功能之一是新的java.util.stream API&#xff0c;正如Javadoc所述&#xff0c;该API支持 …

面向对象克隆对象

克隆对象这种写法不是对象克隆&#xff0c;就是把obj的内存地址赋值给obj2. 通过for in克隆 不管是公有的还是私有的都克隆成私有的 Js提供了一个一个克隆的方法 Object.create() Var obj2Object.create(obj) 将obj的所有属性克隆到obj2的原型上 转载于:https://www.cnblogs.…

JSON.stringify()和JOSN.parse()

JSON.stringify()跟JSON.parse() 终于把这两个方法搞清楚了&#xff01;&#xff01;&#xff01; JSON.tringify()&#xff1a;把一个json数据转化成JSON string JSON.stringify({uno:1,dos:2},null,\t)"{"uno": 1,"dos": 2}"JSON.stringfy({u…

查表法实现反正切_关于python实现CRC32的应用和总结

关于python实现CRC32的应用和总结目前使用的Crc计算包含Crc32和Crc32mpeg2两种计算方式。循环冗余检验 CRC 差错检测技术能够证明数据是完整的&#xff0c;是无差错的&#xff08;只是非常近似的认为是无差错的&#xff09;。保证数据可靠性传输的方法包含如下&#xff1a;检验…