junit5和junit4_JUnit 5 –下一代JUnit的初步了解

junit5和junit4

2月初, JUnit 5(又名JUnit Lambda)团队发布了一个alpha版本。 由于JUnit 4是我工具箱中使用最多的项目之一,因此我认为值得一看下一个主要版本。

我试用了最新版本,并记下了我在这里发现值得注意的更改。

安装JUnit 5

不用说,一个名为JUnit Lambda的项目需要Java 1.8或更高版本。 如果给出了,那么包括库就很简单了。 可从Sonatype的快照存储库( https://oss.sonatype.org/content/repositories/snapshots/org/junit/ )获得当前alpha发行渠道的最新版本。

可以使用Maven和Gradle消耗工件。 如果您希望手动维护依赖关系,那么还有一个可用的zip发行版 ,其中包含编译和运行JUnit 5的所有内容。

在开发时,仅依赖org.junit:junit5-api模块就足够了。

请注意,在指定快照存储库时,应将其配置为从不缓存工件,以便始终使用最新版本。

从JUnit 4减少松动

据我所知,新版本是对库的完全重写,对旧版本没有任何依赖性。 因此,您可以享受传统的免费测试(至少一段时间;-)。

但是,当然有一条迁移路径可以使两个版本共存,并使您能够在使用JUnit 5编写新测试时维护现有测试代码库。

相同但不同

但是,让我们最后来看一下JUnit 5测试的样子。 乍一看,变化不大。 一个简单的测试课程…

class FirstTests {@Testvoid firstTest() {fail();}
}

…与JUnit 4测试几乎没有区别。

但是,您发现细微的差别了吗? 是的,测试不再需要公开,但是如果您愿意,测试当然也可以。

尽管注释仍用于标识设置和拆除测试环境的方法,但其名称已更改。 @BeforeClass/AfterClass现在是@BeforeAll/AfterAll@Before/After现在是@BeforeEach/AfterEach

使用@Disabled批注仍然可以忽略测试。

@Test与@Test

如您所见,测试仍然使用@Test注释标记。 但是要小心,如果您碰巧在类路径上也有JUnit 4。 JUnit 5 @Test自己的@Test批注,因此请确保导入正确的org.junit.gen5.api.Test 。 否则,JUnit 5测试运行程序将找不到您的测试。

要注意的另一件事是新的@Test注释不提供其他服务。 如果你曾经使用timeoutexpected不时,你将需要更换他们的JUnit 5。

使用JUnit 5运行测试

难怪还没有IDE支持可以运行JUnit 5测试。 因此,我使用ConsoleRunner来执行实验。 以这种方式运行测试还需要三个模块:

  • org.junit:junit5-engine
  • org.junit:junit-launcher
  • org.junit:junit-console

我选择的IDE是Eclipse,为了从那里使用ConsoleRunner运行测试,我不得不手动扩展启动配置的Classpath 。 仅在添加包含已编译测试的test-classes输出文件夹之后,它们才会被拾取。 但是,这个怪异也可能是由于我对Maven的了解不足,或者是由于Eclipse Maven集成中的特殊性。

JUnit 5团队还提供了基本的插件来执行Maven和Gradle构建中的测试。 如果您想尝试一下,请参阅“ 构建支持”一章。

断言

乍一看,断言并没有太大变化,只是断言现在位于org.junit.gen5.api.Assertions类中。

但是仔细观察发现, assertThat()消失了,不幸的是依赖于Hamcrest。 这些方法实际上复制了MatcherAssert提供的API, MatcherAssert JUnit的MatcherAssert版本绑定到Hamcrest库。 这种依赖性有时会导致类解析冲突。 特别是与其他库一起使用时,更糟的是,它们会自己包含Hamcrest的副本。

另一个更改是新的assertAll()方法,该方法用于对断言进行分组。 例如

assertAll( "names", () -> {assertEquals( "John", person.getFirstName() );assertEquals( "Doe", person.getLastName() );
} );

将报告一个MultipleFailuresError其中包含组中所有失败的断言。

然后,测试执行者有责任以适当的方式显示此故障。 但是,当前的ConsoleRunner实现尚未考虑分组故障,仅报告第一个故障:

Finished:    testNames [junit5:com...GroupAssertionsTest#testNames()]=> Exception: names (1 failure)expected: <John> but was: <Mary>

我的第一个未经过滤的想法是,如果需要对断言进行分组,则可能是将代码分成多个测试的标志。 但是我还没有真正使用分组断言,并且可能还有一些地方完全有意义。

测试异常

测试异常已经统一。 要更换expectedExpectedException现在有一个expectThrows断言评估lambda表达式,并验证它抛出指定类型的异常。

例如,

@Test
void testException() {Foo foo = new Foo();Throwable exception = expectThrows( IllegalStateException.class, foo::bar );assertEquals( "some message", exception.getMessage() );
}

…如果调用foo::bar()没有抛出IllegalStateException将失败。 否则,将返回抛出的异常,并且可以对其进行进一步验证。 如果引发的异常assertThrows() ,则还有一个assertThrows()方法返回void。

再见亚军,规则和ClassRule

JUnit 5不再知道运行器,规则或类规则。 这些部分竞争的概念已由单个一致的扩展模型代替。

通过使用@ExtendWith注释测试类或测试方法,可以声明性地使用扩展。 例如,希望使用模拟实例初始化某些字段的测试可以使用Mockito扩展,如下所示:

@ExtendWith(MockitoExtension.class)
class MockedTest {@MockPerson person;// ...}

如果您对此主题有更多兴趣,请继续关注有关扩展以及如何将现有规则迁移到我计划编写的自定义扩展的单独文章。

测试方法参数

在JUnit 5中,现在允许方法具有参数。 这允许在方法级别注入依赖项。

为了提供参数,所谓的解析器是必需的,它是实现MethodParameterResolver的扩展。 与所有其他扩展一样,要将解析器用于给定的方法或类,则需要使用@ExtendWith进行声明。 还有两个不需要明确声明的内置解析器。 它们提供类型TestInfoTestReporter参数。

例如:

class MethodParametersTest {@Test// implicitly uses TestInfoParameterResolver to provide testInfovoid testWithBuiltIntParameterResolver( TestInfo testInfo ) {// ...}@Test@ExtendWith( CustomEnvironmentParameterResolver.class )// explicit resolver declared, could also be placed at class levelvoid testWithCustomParameterResolver( CustomEnvironment environment ) {// ...}
}

如果在运行时找不到匹配的参数解析器,则引擎将通过相应的消息使测试失败。

该文档指出,有计划提供其他扩展,其中还包括一个用于动态测试注册的扩展。 有了这个扩展,就有可能进行参数化测试。 考虑到测试方法已经接受了参数,参数化测试似乎也可以在方法级别上使用。

向后兼容

为了缩小差距,直到IDE本地支持JUnit 5为止,有一个JUnit 4 Runner能够执行为JUnit 5编写的测试。使用@RunWith(JUnit5.class)批注来运行测试类和测试套件。

通过该运行器,可以并排运行JUnit 4和5测试类。 在单个测试中混合使用新旧概念当然是@Rule的,例如,将@Rule@ExtendWith等共存。

Mockito和AssertJ等测试实用程序将继续使用新版本,而无需进行更改。 他们通过引发一个异常来与JUnit交互,即使在JUnit 5中,该异常仍然被认为是测试失败:)

JVM开放测试联盟

JUnit Lambda团队还为JVM建立了开放测试联盟 ,其目标是建立一个标准,以促进测试框架,断言库,模拟库,构建工具和IDE之间的交互。

主要目标是提供一个库,该库定义测试框架(例如JUnit,TestNG,Spock等)要使用的一组通用异常,以及断言库。 构建工具和IDE也将受益,因为它们可以依赖相同的类型集,而与测试框架无关。

可以以org.opentest4j库的形式获得实现草案,您可以猜到它是JUnit 5使用的。

外表

我的印象是建立了新版本的基本概念。 诸如@Test,设置和拆卸注释之类的东西,单个扩展模型的概念可能仍会保持当前形状。

但是许多细节似乎尚未解决,API可能会发生变化,我认为这在开发周期的现阶段是可以理解的。 API的每个部分都标有@API注释 ,以指示其稳定性。

如果这篇文章引起了您的兴趣,并且您可能希望浏览文档以获取更多信息,那么还有很多值得探索的地方,例如:

  • 用于过滤测试执行的标签
  • 嵌套测试以对测试进行分组并表达测试组之间的关系
  • 可扩展的思路进行测试验证规则 (如@Test@BeforeEach不应该在同样的方法进行)
  • 在运行时动态注册测试
  • 注释有助于并行运行测试

第一个里程碑计划于2016年第一季度末发布。 此处提供了此发行版中要解决的项目的暂定清单。

翻译自: https://www.javacodegeeks.com/2016/02/junit-5-first-look-next-generation-junit.html

junit5和junit4

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

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

相关文章

python进阶装饰器_老生常谈Python进阶之装饰器

函数也是对象要理解Python装饰器&#xff0c;首先要明白在Python中&#xff0c;函数也是一种对象&#xff0c;因此可以把定义函数时的函数名看作是函数对象的一个引用。既然是引用&#xff0c;因此可以将函数赋值给一个变量&#xff0c;也可以把函数作为一个参数传递或返回。同…

LeetCode 02.两数相加

原题链接 解题思路&#xff1a; 本题可以使用模拟法&#xff0c;从链表的结点中提取出val逐个相加&#xff0c;没有值取0。并且记录进位&#xff0c;每个节点只保留个位数&#xff0c;所以需要使用sum与10取模&#xff0c;如果最高位存在进位则需要在最后添加一个val为1的节点…

apache ignite_从In Memory Data Grid,Apache Ignite快速入门

apache igniteIMDG或内存数据网格不是内存中关系数据库&#xff0c;NOSQL数据库或关系数据库。 它是另一种软件数据存储库。 数据模型分布在单个位置或多个位置的许多服务器上。 这种分布称为数据结构。 这种分布式模型被称为“无共享”架构。 IMDG具有以下特征&#xff1a; 所…

bvp解算器是什么_那些学习了编程的中学生,为什么会更可能成功?

来源 | 异步当你看到这个题目&#xff0c;或许会想&#xff0c;这不是搞笑吗&#xff1f;众所周知&#xff0c;高等数学是编程的基础和前提&#xff0c;而说起程序编写员&#xff0c;在普通人眼里就是数学学霸的代名词&#xff0c;人们往往会把它和那些数学天才的名字联系在一起…

Leetcode 08. 字符串转换整数 (atoi)

原题链接 1.字符 0~~~~~9 分别对应整数 48~~~~~57 2.先过滤空白 3.确定前面所带的符号 4. long long res 0; res res * 10 str[k] - 0; 可以通过此方法从左到右高位逐个累加。 class Solution { public:int myAtoi(string str) {long long res 0;int k 0;while…

maven与spring_与Spring和Maven签约首个SOAP服务

maven与spring1.简介 在本教程中&#xff0c;我们将学习使用JAX-WS&#xff0c;Spring和Maven实施合同优先的SOAP服务应用程序。 这是使用合同优先还是代码优先方法的更多设计决定。 在开发基于SOAP的Web服务应用程序时使用应用合同优先的方法最显着的好处是&#xff0c;可以在…

如何维持手机电池寿命_充电小知识:你知道如何正确充电吗?这几种充电方式最损害电池...

目前基本上大部分人都至少有一部智能手机&#xff0c;智能手机基本上都需要每日一充&#xff0c;你的充电方式会不会损伤电池呢&#xff1f;有部分消费者认为要等到手机电量耗尽后再充电&#xff0c;还有人认为手机充电要充至100%才能拔下来&#xff0c;有人觉得充电宝等产品给…

【开放集检测】OpenGAN: Open-Set Recognition via Open Data Generation 论文阅读

文章目录 英语积累为什么使用GAN系列网络进行开放集检测摘要1. 前言2. 相关工作开集检测基于GAN网络的开集检测基于暴露异常数据的开集检测 3. OpenGAN3.1 公式建模3.1.1 二分类方法存在问题如何解决 3.1.2 使用合成数据存在问题如何解决 3.1.3 OpenGAN3.1.4 模型验证 3.2 先前…

LeetCode 27.移除元素

原题链接 /** lc appleetcode.cn id27 langcpp** [27] 移除元素标签&#xff1a;拷贝覆盖主要思路是遍历数组nums&#xff0c;每次取出的数字变量为num&#xff0c;同时设置一个下标ans在遍历过程中如果出现数字与需要移除的值不相同时&#xff0c;则进行拷贝覆盖nums[ans] n…

hotspot 默认 gc_默认HotSpot最大直接内存大小

hotspot 默认 gc在我以前的博客文章热点选项中的Java 8改进的文档 &#xff0c;我写的误解围绕热点JVM非标准的默认设置选项 -XX:MaxDirectMemorySize 。 在本文中&#xff0c;我介绍了一种确定HotSpot JVM中“默认”最大直接内存大小的简单方法。 Java启动器的Java 8文档对-X…

python控制电脑休眠唤醒键_每当计算机从休眠状态唤醒时,都运行python脚本

我在python上编写了一个小脚本,该脚本从控制台调用命令行以使linux机器休眠(或在更改一个单词的情况下将其自身关闭),然后在一段时间后唤醒.通过watch命令一次又一次地调用该命令.import osimport timeos.system("watch -n 20 sudo rtcwake -u -s 10 -m mem")因此,在…

sso集成shiro_Keycloak SSO集成到jBPM和Drools Workbench中

sso集成shiro介绍 单一登录&#xff08;SSO&#xff09;和相关令牌交换机制正在成为Web上不同环境中身份验证和授权的最常见方案&#xff0c;尤其是在迁移到云中时。 本文讨论了Keycloak与jBPM或Drools应用程序的集成&#xff0c;以便使用Keycloak上提供的所有功能。 Keycloak…

LeetCode 01. 两数之和

原题 分析&#xff1a; 1.根据题意&#xff0c;首先需要将要数据选择一个合适的 数据结构模型。 因为是对应相关联&#xff0c;所以我们选择unordered_map 2.因为是一组数&#xff0c;所以用数组 &#xff0c;将数值与数组下标对应起来 3.已知两数之和&#xff0c;从数组第…

python中自带的模块_python中的模块详解

概念python中的模块是什么&#xff1f;简而言之&#xff0c;在python中&#xff0c;一个文件(以“.py”为后缀名的文件)就叫做一个模块&#xff0c;每一个模块在python里都被看做是一个独立的文件。模块可以被项目中的其他模块、一些脚本甚至是交互式的解析器所使用&#xff0c…

剑指 Offer 51-----59

剑指 Offer 55 - I. 二叉树的深度 解题思路&#xff1a; class Solution { public:int maxDepth(TreeNode* root) {if(rootNULL)return 0;int lmaxDepth(root->left);int rmaxDepth(root->right);return (l>r?l:r)1;} };

jbpm 和 drools_jBPM和Drools工作台中的用户和组管理

jbpm 和 drools介绍 本文讨论了一项新功能&#xff0c;该功能允许使用集成在jBPM和Drools Workbenches中的直观友好的用户界面来管理应用程序的用户和组。 用户和组管理 在安装&#xff0c;设置和使用此功能之前&#xff0c;本文讨论了一些以前的概念&#xff0c;需要进一步理…

剑指 Offer 01-----20

剑指 Offer 03. 数组中重复的数字 解题思路&#xff0c;使用STL中的set&#xff0c;逐个读入vector中的每一个元素&#xff0c;使用set进行对比&#xff0c;如果set中存在会返回1&#xff0c;这时直接返回该元素即可&#xff1b;如果set中没有可以insert这个元素到set&#xf…

python filter函数中写none_Python3基础 filter 第一个参数为NONE时 结果只返回为True的对象...

Python : 3.7.0OS : Ubuntu 18.04.1 LTSIDE : PyCharm 2018.2.4Conda : 4.5.11typesetting : Markdowncode"""Author : 行初心Date : 18-9-23Blog : www.cnblogs.com/xingchuxinGitee : gitee.com/zhichengjiu"""def main():# 过滤器# 通过 过滤…

从事java编程技能要求_5道Java视频课程,提高您的编程技能

从事java编程技能要求作为Web开发人员&#xff0c;跟上技术知识可能会很棘手。 新技术似乎每天都在弹出&#xff0c;而基本技术也看到了重复迭代的浪潮&#xff0c;增加了新的功能。 Java开发人员应该做什么&#xff1f; 这是在线教育平台发挥作用的地方。 它们可以帮助您快速…

常见算法核心思想

双指针算法 1.双指针算法主要是为了提高朴素算法的复杂度&#xff0c;即O(n^2)的算法&#xff0c;优化为O(n)的算法。 2.常见模板 for (int i 0, j 0; i < n; i ) {while (j < i && check(i, j)) j ;// 具体问题的逻辑 } 常见问题分类&#xff1a;(1) 对于…