热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

JUnit5相关内容简介

这篇文章主要介绍了JUnit5相关内容简介,具有一定借鉴价值,需要的朋友可以参考下

著名的Java单元测试框架Junit 4已经出来很长时间了,当时我发现JUnit 5已经处于测试版,就准备写文章来介绍JUnit 5.不过因为还是测试版,所以有些地方还不太完善,我也有点懒没有好好写。这几天突然想起这事了,在到官网上查看,发现就在9月10日,JUnit 5的正式版终于出来了!那么我就正好把文章重新好好写写,为大家介绍这个最新的JUnit框架。

框架结构

和JUnit 4相比,JUnit 5的结构非常清晰,为自定义插件、IDE测试执行等扩展功能做了很好的支持。这一点从项目结构就可以看出来。

JUnit Platform

这一组的包名是org.junit.platform,从名字就可以看到,这一组的主要功能就是作为测试框架的基础平台。这个包下的模块包含基础API、执行引擎及执行器、基本的命令行执行功能、命令行界面、Maven及Gradle的测试插件等最基本的功能。

JUnit Jupiter

Jupiter 是JUnit 5的代号,这个包下的模块包含JUnit 5的主要功能。如果我们要使用JUnit 5,那么必然要包含这一组模块。

JUnit Vintage

Vintage 是旧版本JUnit 的代号,这个包下的模块可以让我们在新的JUnit平台上运行旧的JUnit 3 和 4 的测试。

导入类库

在JUnit 5还在测试阶段的时候,官方文档上还有在Maven和Gradle中集成JUnit 5的例子。但是到了正式版,这一部分的内容消失了,仅仅留下两个示例项目的链接,让我们自己参考(复制粘贴)。

使用Maven

junit5-maven-consumer 是官方的Maven例子。本来我准备把相关的POM配置贴到这里,但是一看Maven的配置太长了,所以还是算了。如果有需求的话请自己查看这个项目的POM配置。

使用Gradle

如果用Gradle的话,那么这个问题就简单多了。在junit5-gradle-consumer 示例项目中也有比较详细的说明。

首先,Gradle默认不支持JUnit 5,,所以需要启用JUnit Platform Gradle 插件来支持。

buildscript {
 repositories {
 mavenCentral()
 }
 dependencies {
 classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0'
 }
}
apply plugin: 'org.junit.platform.gradle.plugin'

然后是关于这个Gradle插件的配置。默认情况下所有的引擎和标签都会被执行。如果你想选择只执行某些引擎和标签的测试,可以取消下面的注释并按照你自己的需求进行修改。当然假如你没有这些高级需求,可以把这一部分删掉。

junitPlatform {
 // platformVersion '1.0.0'
 filters {
 engines {
  // include 'junit-jupiter', 'junit-vintage'
  // exclude 'custom-engine'
 }
 tags {
  // include 'fast'
  exclude 'slow'
 }
 // includeClassNamePattern '.*Test'
 }
 // enableStandardTestTask true
 // reportsDir file('build/test-results/junit-platform') // this is the default
 // logManager 'org.apache.logging.log4j.jul.LogManager'
}

如果你只需要运行JUnit 5测试,只需要导入下面两个依赖项。JUnit Platform的依赖会自动导入。

dependencies {
 testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0")
 testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0")
}

如果你想在新平台下运行旧的JUnit 3和4测试,需要导入下面的依赖项。

dependencies {
 testCompile("junit:junit:4.12")
 testRuntime("org.junit.vintage:junit-vintage-engine:4.12.0")
}

编写测试

JUnit 4测试

如果前面都配置好了,现在就可以开始编写测试了。首先先来复习一下旧的JUnit 4测试。

public class JUnit4Test {
	@BeforeClass
	 public static void init() {
		System.out.println("Before Class");
	}
	@AfterClass
	 public static void clean() {
		System.out.println("After class");
	}
	@Before
	 public void before() {
		System.out.println("Before");
	}
	@After
	 public void after() {
		System.out.println("After");
	}
	@Test
	 public void test1() {
		System.out.println("Test 1");
	}
	@Test
	 public void test2() {
		System.out.println("Test 2");
	}
}

使用gradle test等命令执行一下,就会执行这个测试。结果类似于这样。

Before Class
Before
Test 1
Test 2
After
After class

JUnit 5测试

让我们来看看等效的JUnit 5测试怎么写。可以看到最明显的变化:首先几个注解被重新命名成更见名知义的名称;另外一点是测试方法不必是公有方法,这样我们可以少敲几下键盘。

public class JUnit5Test {
	@BeforeAll
	 static void beforeAll() {
		System.out.println("Before All");
	}
	@AfterAll
	 static void afterAll() {
		System.out.println("After All");
	}
	@BeforeEach
	 void before() {
		System.out.println("Before");
	}
	@AfterEach
	 void after() {
		System.out.println("After");
	}
	@Test
	 void test1() {
		System.out.println("Test 1");
	}
	@Test
	 void test2() {
		System.out.println("Test 2");
	}
}

编写断言

为了验证测试用例是否正确,我们需要编写一些断言。JUnit 5自带了很多断言,可以帮助我们编写测试用例。而且这些断言都带有可以接受lambda表达式的重载版本,非常适合Java 8使用。当然我个人认为断言还是AssertJ更方便一点。

import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.*;

public class AssertionDemo {
 @Test
 void testAssertion() {
 assertEquals(10, 10);
 assertTrue(true);
 assertEquals(100, 100, "两个数相等");
 assertAll("数字"
  , () -> assertEquals("name", "name")
  , () -> assertEquals(500, 500));
 assertThrows(InvalidParameterException.class
  , () -> {
   throw new InvalidParameterException();
  }
 );
 int result = assertTimeout(Duration.ofSeconds(5)
  , () -> {
   int i = 0, j = 0;
   while (i <= 100) {
   for (; j <= 100000; j++)
    j++;
   i++;
   }
   return i;
  });
 assertEquals(100, result);
 }
}

依赖注入

现在测试类的构造方法和测试方法都可以接受参数了。ParameterResolver接口定义了如何在运行时注入参数的方法。内置的几个可以让我们获取测试用例运行时的信息。

首先是TestInfoParameterResolver。如果方法上有TestInfo类型的实例,JUnit 5框架就会自动注入该实例,这个实例的几个方法可以让我们获取测试类和测试方法的名称、显示名称、标签等信息。

public class DependencyInjectionDemo {
 @Test
 @DisplayName("依赖注入")
 @Tag("test")
 void testDisplayName(TestInfo testInfo) {
 assertEquals("依赖注入", testInfo.getDisplayName());
 assertEquals(Collections.singleton("test"), testInfo.getTags());
 }
}

还有RepetitionInfoParameterResolver等内置参数解析器,将在后面介绍。

常用注解

显示名称

我们可以为测试类和测试方法添加自定义的名称,这些名贵会由测试运行器和测试报告所显示。显示名称没有变量名那样的显示,可以是一段包含空格的长字符串,甚至还可以是Emoji表情。

@DisplayName("测试类可以指定显示名称")
public class DisplayNameDemo {
	@Test
	 @DisplayName("测试方法也可以指定显示名称")
	 void testWithLongDisplayName() {
	}
	@Test
	 @DisplayName("显示名称还可以包含表情&#65533;&#65533;")
	 void testWithDisplayNameWithEmoji() {
	}
}

禁用测试

@Disabled注解可以用到测试类或测试方法上,可以禁用对应的测试。

@Disabled
public class DisabledTestDemo {
 @Test
 //@Disabled
 void testDisabled() {

 }
}

重复测试

如果需要让某个测试方法运行多次,使用@RepeatedTest注解。

public class RepeatedTestDemo {
 @RepeatedTest(10)
 void testRepeated10Times() {

 }
}

还可以注入一个实例RepetitionInfo,检查当前重复次数和总的重复次数。

public class RepeatedTestDemo {
	@BeforeEach
	 void beforeEach(RepetitionInfo info) {
		System.out.printf("%d - %d\n"
		    , info.getCurrentRepetition()
		    , info.getTotalRepetitions());
	}
	@RepeatedTest(10)
	 void testRepeated10Times() {
	}
}

附带标签

在前面介绍配置Gradle的时候就说了,在配置中可以选择过滤某些标签的测试。要在代码中给标签也很简单,直接用@Tag注解即可。

@Tag("taggedTest")
public class TagDemo {
	@Test
	 @Tag("taggedTest1")
	 void testWithTag1() {
	}
	@Test
	 @Tag("taggedTest2")
	 void testWithTag2() {
	}
}

嵌套测试

有时候可能需要嵌套测试来表明某些测试之间的包含关系。嵌套测试使用@Nested注解。

@DisplayName("外层测试")
public class NestedDemo {
 @Test
 void testOuter() {
 }

 @Nested
 @DisplayName("内层测试")
 class InnerTestDemo {
  @Test
  void testInner() {
  }
 }
}

需要注意只有费静态内部类才能使用Nested注解。另外,由于Java不允许内部类有静态方法,所以也不能有@BeforeAll和@AfterAll注解。如果想要突破这个限制,需要在嵌套内部类上添加@TestInstance(Lifecycle.PER_CLASS)注解,详情参见Test Instance Lifecycle。

IDE支持

虽然现在JUnit 5已经出来了。但是各种工具链的支持还没有跟上。目前只有Intellij IDEA和Eclipse 4.7 (Oxygen)添加了对JUnit 5的支持。所以如果在正式场合的话,使用JUnit 4还是更稳妥一点。

常见问题

区分不同版本间的@Test注解

就在我写这篇文章的时候, 我的测试小例子就遇到了一个问题,测试通不过,显示如下的错误信息。

Failures (1):
 JUnit Vintage:yitian.study.test.AssertionDemo:initializationError
 ClassSource [className = 'yitian.study.test.AssertionDemo', filePosition = null]
 => java.lang.Exception: Method testAssertion() should be public

英文好的同学应该可以认出来,这个错误信息说的是测试方法必须是公开的。但是前面明明说了,JUnit 5取消了这个限制,那么为什么还会出现这个错误呢?我仔细一看,发现了错误所在。可能是由于以前JUnit 4用的比较多,所以IDE默认对于@Test这个注解,自动补全的是这个。

import org.junit.Test;

这个包是JUnit 4下的@Test注解。如果我们要使用JUnit 5的话,需要的是以下这个@Test注解。

import org.junit.jupiter.api.Test;

修改之后,再次运行测试,果然没有问题了。当然这里为了学习和使用,我同时引用了JUnit 4的包,所以才会出现这个冲突。如果没有什么特殊需求的话,建议只导入JUnit 5的jar包,防止出现混淆。当然都导入也可以,只不过你就需要小心区分,不要把JUnit 4的注解写到JUnit 5的测试上。最后附上我的测试小例子,有兴趣的同学可以看看。

总结

以上就是本文关于JUnit5相关内容简介的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


推荐阅读
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 项目运行环境配置及可行性分析
    本文介绍了项目运行环境配置的要求,包括Jdk1.8、Tomcat7.0、Mysql、HBuilderX等工具的使用。同时对项目的技术可行性、操作可行性、经济可行性、时间可行性和法律可行性进行了分析。通过对数据库的设计和功能模块的设计,确保系统的完整性和安全性。在系统登录、系统功能模块、管理员功能模块等方面进行了详细的介绍和展示。最后提供了JAVA毕设帮助、指导、源码分享和调试部署的服务。 ... [详细]
  • Struts2+Sring+Hibernate简单配置
    2019独角兽企业重金招聘Python工程师标准Struts2SpringHibernate搭建全解!Struts2SpringHibernate是J2EE的最 ... [详细]
  • Maven构建Hadoop,
    Maven构建Hadoop工程阅读目录序Maven安装构建示例下载系列索引 序  上一篇,我们编写了第一个MapReduce,并且成功的运行了Job,Hadoop1.x是通过ant ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 本文介绍了在Java开发中创建子包(package)的正确步骤,并解析了可能出现的错误情况。其中包括第一种错误情况的解决方法,以及在空包下只建一个包时可能出现的问题及解决方法。通过多建几个包,可以让IDE自动将父包提取出来,形成正确的层次结构。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • PreparedStatement防止SQL注入
    添加数据:packagecom.hyc.study03;importcom.hyc.study02.utils.JDBCUtils;importjava.sql ... [详细]
  • 一、Struts2是一个基于MVC设计模式的Web应用框架在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2优点1、实现 ... [详细]
  • linux系统重装win7 磁盘格式为gpt,怎么更改为,win10改win7怎么将硬盘格式由gpt转mbr?...
    [文章导读]随着近两年发布的笔记本、台式机等预装的全是win10系统,但有些用户还是想用win7,所以就有很多用户问win10怎么改win7系统呀&#x ... [详细]
  • 弹性云服务器ECS弹性云服务器(ElasticCloudServer)是一种可随时自助获取、可弹性伸缩的云服务器,帮助用户打造可靠、安全、灵活、高效的应用环境 ... [详细]
author-avatar
陈晏亚363951
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有