junit5和junit4_JUnit 5 –基础
junit5和junit4
JUnit 5是适用于Java的下一代单元测试框架,具有许多有趣的功能,包括嵌套测试,参数化测试,新的扩展API或Java 8支持。
本文展示了JUnit 5的基本概念,包括测试生命周期,参数注入和声明(基本,超时和异常)。
文献资料
首先,我认为JUnit 5文档很棒。 它不仅包含全面的框架文档,还包含许多示例,包括许多示例。 学习JUnit 5时不要错过文档: http : //junit.org/junit5/docs/current/user-guide/
依存关系
首先,JUnit 5需要Java 8才能运行。 最后。 这带来了在测试中使用Lambda表达式的可能性,并使它们更加简洁(Lambda表达式主要用于断言中)。 其次,JUnit 5由按JUnit Platform,JUnit Jupiter和JUnit Vintage分组的多个工件组成。 这听起来可能很吓人,但是如今使用Maven或Gradle之类的工具根本不是问题,要开始使用,您实际上只需要一个依赖项。 Gradle的基本配置如下所示:
buildscript {ext {junitPlatformVersion = '1.0.1'junitJupiterVersion = '5.0.1'}repositories {mavenCentral()}dependencies {classpath "org.junit.platform:junit-platform-gradle-plugin:${junitPlatformVersion}"}
}apply plugin: 'java'
apply plugin: 'org.junit.platform.gradle.plugin'sourceCompatibility = 1.8repositories {mavenCentral()
}dependencies { testRuntime("org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}")
}task wrapper(type: Wrapper) {gradleVersion = '4.1'
}
JUnit 5测试类和方法
在测试类(从org.junit.jupiter.api
导入)中使用的常见测试注释是:
@BeforeAll
–在测试类中的所有方法之前执行@BeforeEach
–在测试类中的每个测试方法之前执行@Test
–实际测试方法@AfterEach
–在测试环境中的每个测试方法之后执行@AfterAll
–在测试方法中的所有方法之后执行
其他基本但有用的注释:
@DisplayName
–测试类或方法的自定义显示名称@Disabled
–禁用测试类或方法@RepeatedTest
–用测试方法制作测试模板@Tag
–标记测试类或方法以进一步选择测试
一个基本的例子:
import org.junit.jupiter.api.*;@DisplayName("JUnit5 - Test basics")
class JUnit5Basics {@BeforeAllstatic void beforeAll() {System.out.println("Before all tests (once)");}@BeforeEachvoid beforeEach() {System.out.println("Runs before each test");}@Testvoid standardTest() {System.out.println("Test is running");}@DisplayName("My #2 JUnit5 test")@Testvoid testWithCustomDisplayName() {System.out.println("Test is running");}@DisplayName("Tagged JUnit5 test ")@Tag("cool")@Testvoid tagged() {System.out.println("Test is running");}@Disabled("Failing due to unknown reason")@DisplayName("Disabled test")@Testvoid disabledTest() {System.out.println("Disabled, will not show up");}@DisplayName("Repeated test")@RepeatedTest(value = 2, name = "#{currentRepetition} of {totalRepetitions}")void repeatedTestWithRepetitionInfo() {System.out.println("Repeated test");}@AfterEachvoid afterEach() {System.out.println("Runs after each test");}
}
请注意,测试类和方法不必是公共的 ,它们可以是包私有的 。
测试执行生命周期
在JUnit 5中,默认情况下会为测试类中的每个测试方法创建一个新的测试实例。 可以使用类级别@TestInstance
注释来调整此行为:
import org.junit.jupiter.api.*;@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@DisplayName("JUnit5 - Test lifecycle adjustments")
class JUnit5PerClassLifecycle {private Object first = new Object();private Object second;@BeforeAllvoid beforeAll() {this.second = this.first;System.out.println("Non static before all.");}@BeforeEachvoid beforeEach() {Assertions.assertEquals(first, second);}@Testvoid first() {Assertions.assertEquals(first, second);}@Testvoid second() {Assertions.assertEquals(first, second);}@AfterAllvoid afterAll() {System.out.println("Non static after all.");}@AfterEachvoid afterEach() {Assertions.assertEquals(first, second);}
}
在PER_CLASS
模式下,将为所有测试创建单个测试实例,并且@BeforeAll
和@AfterAll
方法不再需要是静态的。
参数解析
测试和回调方法现在可以采用org.junit.jupiter.api.TestInfo
, org.junit.jupiter.api.RepetitionInfo
或org.junit.jupiter.api.TestReporter
类的参数。
此外,由于使用了非常简单但功能强大的JUnit 5扩展API,因此在方法中解析自定义参数只需提供自己的org.junit.jupiter.api.extension.ParameterResolver
实现即可。
class JUnit5BuiltInParameterResolution {@BeforeAllstatic void beforeAll(TestInfo testInfo) {System.out.println("Before all can take parameters. Started: " + testInfo.getDisplayName());}@BeforeAllstatic void beforeAll(TestReporter testReporter) {testReporter.publishEntry("myEntry", "myValue");}@BeforeAllstatic void beforeAll(TestInfo testInfo, TestReporter testReporter) {testReporter.publishEntry("myOtherEntry", testInfo.getDisplayName());}@BeforeEachvoid beforeEach(TestInfo testInfo) {}@Testvoid standardTest(TestInfo testInfo) {}@DisplayName("Repeated test")@RepeatedTest(value = 2, name = "#{currentRepetition} of {totalRepetitions}")void repeatedTest(RepetitionInfo repetitionInfo) {System.out.println("Repeated test - " + repetitionInfo.toString());}@AfterAllstatic void afterAll() {}@AfterAllstatic void afterAll(TestInfo testInfo) {}@AfterEachvoid afterEach() {}
}
断言
JUnit 5带有许多标准断言,可以在org.junit.jupiter.api.Assertions
类中找到。
基本断言
基本主张是: assertEquals
, assertArrayEquals
, assertSame
, assertNotSame
, assertTrue
, assertFalse
, assertNull
, assertNotNull
, assertLinesMatch
, assertIterablesMatch
例:
@Test
void basicAssertions() {// arrangeList<String> owners = Lists.newArrayList("Betty Davis", "Eduardo Rodriquez");// assertassertNotNull(owners);assertSame(owners, owners);assertFalse(owners::isEmpty); // Lambda expressionassertEquals(2, owners.size(), "Found owner names size is incorrect");assertLinesMatch(newArrayList("Betty Davis", "Eduardo Rodriquez"), owners);assertArrayEquals(new String[]{"Betty Davis", "Eduardo Rodriquez"}, owners.toArray(new String[0]));
}
断言所有
Assertions.assertAll
断言所有提供的可执行文件均不会引发异常:
Assertions.assertAll(() -> Assertions.assertNotNull(null, "May not be null"),() -> Assertions.assertTrue(false, "Must be true")
);
上面将报告多个失败:
org.opentest4j.MultipleFailuresError: Multiple Failures (2 failures)May not be null ==> expected: not <null>Must be true
注意:您可能想阅读有关JUnit 4和AssertJ中的替代方法的信息-http: //blog.codeleak.pl/2015/09/assertjs-softassertions-do-we-need-them.html
超时断言
使用超时断言来验证未超过任务的执行时间。 超时断言有两种: assertTimeout
和assertTimeoutPreemptively
。 都拿两个
- 同步执行任务,等待任务完成,然后声明超时:
@Test
void assertTimeout() {// arrangeExecutable task = () -> Thread.sleep(1000);// waits for the task to finish before failing the testAssertions.assertTimeout(Duration.ofMillis(100), task::execute);
}@Test
void assertTimeoutWithThrowingSupplier() {// arrangeThrowingSupplier<String> task = () -> "result";// waits for the task to finish before failing the testAssertions.assertTimeout(Duration.ofMillis(100), task::get);
}
- 异步执行任务(在新线程中),到超时时中止执行:
@Test
void assertTimeoutPreemptively() {// arrangeExecutable task = () -> Thread.sleep(1000);// abort execution when timeout exceededAssertions.assertTimeoutPreemptively(Duration.ofMillis(100), task::execute);
}@Test
void assertTimeoutPreemptivelyWithThrowingSupplier() {// arrangeThrowingSupplier<String> task = () -> "result";// abort execution when timeout exceeded, return the resultString result = Assertions.assertTimeoutPreemptively(Duration.ofMillis(100), task::get);Assertions.assertEquals("result", result);
}
异常断言
JUnit 5内置的assertThrows
获取预期的异常类型作为第一个参数,而可执行文件(功能接口)则可能将异常作为第二个参数。 如果未引发任何异常或其他类型的异常,则该方法将失败。 该方法返回异常本身,该异常可用于进一步的声明:
@Test
void assertException() {// arrangeExecutable throwingExecutable = () -> {throw new RuntimeException("Unexpected error!");};// act and assertRuntimeException thrown = Assertions.assertThrows(RuntimeException.class, throwingExecutable::execute, "???");Assertions.assertAll(() -> Assertions.assertEquals("Unexpected error!", thrown.getMessage()),() -> Assertions.assertNotNull(thrown.getCause()));
}
注意:您可能想阅读有关JUnit 4中的替代方法的信息-http: //blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html
摘要
JUnit 5具有许多功能。 在本文中,仅演示了基础知识,但这足以让您开始编写第一个JUnit 5测试。
也可以看看
- 使用JUnit 5进行更清洁的参数化测试– http://blog.codeleak.pl/2017/06/cleaner-parameterized-tests-with-junit-5.html
翻译自: https://www.javacodegeeks.com/2017/10/junit-5-basics-2.html
junit5和junit4
junit5和junit4_JUnit 5 –基础相关推荐
- junit5和junit4_JUnit 5 –设置
junit5和junit4 2015年11月, JUnit Lambda团队展示了他们的原型 . 此后,该项目更名为JUnit 5,并于2016年2月发布了Alpha版本.我们将在一系列简短文章中进行 ...
- junit5和junit4_JUnit 5 –架构
junit5和junit4 现在我们知道如何设置JUnit 5并使用它编写一些测试 ,下面让我们看一下. 在本文中,我们将讨论JUnit 5架构以及采用这种方式的原因. 总览 这篇文章是有关JUnit ...
- junit5和junit4_JUnit 5符合AssertJ
junit5和junit4 JUnit 5在断言库中带来了很多改进,这主要归功于Java 8和Lambda Expression的支持以及新断言(如assertAll , assertTimeout或 ...
- junit5和junit4_JUnit 5 –下一代JUnit的初步了解
junit5和junit4 2月初, JUnit 5(又名JUnit Lambda)团队发布了一个alpha版本. 由于JUnit 4是我工具箱中使用最多的项目之一,因此我认为值得一看下一个主要版本. ...
- junit5和junit4_JUnit 5 –条件
junit5和junit4 最近,我们了解了JUnit的新扩展模型以及它如何使我们能够将自定义行为注入测试引擎. 我向你保证要看情况. 现在就开始吧! 条件允许我们在应该执行或不应该执行测试时定义灵活 ...
- junit5和junit4_JUnit声明异常– JUnit 5和JUnit 4
junit5和junit4 We can test expected exceptions using JUnit 5 assertThrows assertion. This JUnit asser ...
- Java基础学习总结(101)——Junit5抢鲜看
JUnit 4的发布背1. Java 8支持景现状 Mr.JUnit 4.0 发布于2006年2月,来看看当时社区的反映: Great!This is the best message I seen ...
- JUnit5学习之六:参数化测试(Parameterized Tests)基础
| :-- | :-- | :-- | | 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 | | git仓库地址(https ...
- 「译」JUnit 5 系列:基础入门
2019独角兽企业重金招聘Python工程师标准>>> 原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, ...
最新文章
- 大三Java后端暑期实习面经总结——Java容器篇
- [转]《我眼中的技术高手》——邯郸学步、创作与创新
- 解决Tomcat下IntelliJ IDEA报错java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
- 为什么要娶就娶电力女?!
- python url拼接_详解Python urlencode编码和url拼接方法
- pytorch 和 tensorflow2.0 方法替换
- easyui datagrid reload后自动全选解决
- Mouse Without Border 无法安装问题
- MFC中让自定义的类能响应消息
- 伸缩Kubernetes到2500个节点中遇到的问题和解决方法
- docker常用操作(三) docker安装maven私服
- part5 vue和HTML5相关知识总结
- cross product or vector product - 叉积或向量积
- 视频的基本参数及H264编解码相关概念
- [转载] COM 套间
- Linux设备模型-1-主要概念
- jsliang 陪你瞎叨叨 2
- Nginx支持url不区分大小写
- 用css改变图片背景色颜色
- 大中型企业敏捷转型策略路线图-案例解析
热门文章
- Codeforces Round #727 (Div. 2) 题解
- 【学习笔记】原根 / BSGS / 扩展BSGS证明及模板
- codeforces:CF1604 总结
- P2469-[SDOI2010]星际竞速【费用流】
- P7276-送给好友的礼物【dp】
- CF961G-Partitions【斯特林数】
- Codeforces Round #659 (Div. 2)
- 【图论】【模板】静态仙人掌(luogu 5236)
- [XSY] 计数(DP,NTT,分治)
- Java 必须掌握的 12 种 Spring 常用注解