JUnit 5 入门指南 - 01.快速上手

JUnit 5 介绍

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

JUnit Platform是在JVM上 启动测试框架 的基础平台。它还定义了 TestEngine API,该API可用于开发在平台上运行的测试框架。此外,平台还提供了一个从命令行或者 Gradle 和 Maven 插件来启动的 控制台启动器 ,它就好比一个 基于JUnit 4的Runner 在平台上运行任何TestEngine。

JUnit Jupiter是一个组合体,它是由在JUnit 5中编写测试和扩展的新编程模型 和扩展模型组成。另外,Jupiter子项目还提供了一个TestEngine,用于在平台上运行基于Jupiter的测试。

JUnit Vintage提供了一个TestEngine,用于在平台上运行基于JUnit 3和JUnit 4的测试。

(通俗的讲,Junit是一个Java 单元测试框架。)

相关在线资料
官网主页

https://junit.org/junit5/

官网文档

https://junit.org/junit5/docs/current/user-guide/

GitHub - 项目源码

https://github.com/junit-team/junit5

GitHub - 示例源码

https://github.com/junit-team/junit5-samples

快速体验

引入依赖

JUnit需要Java8以上的运行环境。

Maven
<dependencies>
	<dependency>
		<groupId>org.junit.jupiter</groupId>
		<artifactId>junit-jupiter</artifactId>
		<version>5.6.1</version>
		<scope>test</scope>
	</dependency>
</dependencies>
Gradle
dependencies {
	testImplementation('org.junit.jupiter:junit-jupiter:5.6.1')
}
SHOW ME THE CODE
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class HelloJunit5 {

    @Test
    void addition() {
        assertEquals(2, 1+1);
    }

}

标准测试类

import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.*;

@DisplayName("一个标准的测试类")
public class StandardTest {

    @BeforeAll
    static void beforeAll() {
        System.out.println("beforeAll");
    }

    @BeforeEach
    void beforeEach() {
        System.out.println("beforeEach");
    }

    @Test
    @DisplayName("一个普通的测试方法")
    void succeedingTest() {
        System.out.println("succeedingTest");
    }

    @Test
    @DisplayName("一个不普通的测试方法")
    void failingTest() {
        fail("a failing test");
    }

    @Test
    @Disabled()
    void skippedTest() {
        System.out.println("skippedTest");
    }

    @AfterEach
    void afterEach() {
        System.out.println("afterEach");
    }

    @AfterAll
    static void afterAll() {
        System.out.println("afterAll");
    }

}

运行结果:

beforeAll
beforeEach
succeedingTest
afterEach
beforeEach
afterEach

org.opentest4j.AssertionFailedError: a failing test
	...此处省略大量栈信息

void StandardTest.skippedTest() is @Disabled
  • 一个标准的生命周期如下
    • beforeAll -> (beforeEach -> test -> afterEach) * @Test -> afterAll
  • 使用@Disabled()可以跳过测试。
  • @DisplayName,看上去优雅的注释方式。

断言 Assert

虽然org.junit.jupiter.api.Assertions满足了大部分场景,但是官方团队还是推荐开发者使用第三方断言类库,例如:AssertJ、Hamcrest、Truth 等等。

假设 Assumpt

org.junit.jupiter.api.Assumptions这个类非常微妙,我实在看不出有什么意义。

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assumptions.*;
import static org.junit.jupiter.api.Assertions.*;

public class AssumptionsTest {

    @Test
    @Disabled
    public void assumeTrueT(){
        //真没看出有啥区别
        assumeTrue(false);
        assertTrue(false);
    }

    @Test
    public void test2(){
        //我写if-else,它不香吗?
        assumingThat(true,
                () -> {
                    System.out.println("1");
                });
    }

}

附录

官方注解

被@Test、@TestTemplate、@RepeatedTest、@BeforeAll、@AfterAll、@BeforeEach 或 @AfterEach 注解标注的方法不可以有返回值。

@Test

表示该方法是一个测试方法。与JUnit 4的@Test注解不同的是,它没有声明任何属性,因为JUnit Jupiter中的测试扩展是基于它们自己的专用注解来完成的

@ParameterizedTest

表示该方法是一个参数化测试,value设置重复次数。

@RepeatedTest

表示该方法是一个重复测试的测试模板。

@TestFactory

表示该方法是一个 动态测试 的测试工厂。

@TestInstance

用于配置所标注的测试类的 测试实例生命周期。

@TestTemplate

表示该方法是一个 测试模板,它会依据注册的 提供者 所返回的调用上下文的数量被多次调用。

@TestMethodOrder

用于配置的测试方法执行顺序测试类注释;类似于JUnit 4的@FixMethodOrder。

@TestInstance

用于配置的测试实例生命周期带注释的测试类。

@DisplayName

为测试类或测试方法声明一个自定义的显示名称。

@DisplayNameGeneration

为测试类声明一个自定义的显示名称生成器。

@BeforeEach

表示使用了该注解的方法应该在当前类中每一个使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之前 执行;类似于JUnit 4的@Before。

@AfterEach

表示使用了该注解的方法应该在当前类中每一个使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之后 执行;类似于JUnit 4的@After。这样的方法会被继承,除非它们被覆盖。

@BeforeAll

表示使用了该注解的方法应该在当前类中所有使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之前 执行;类似于JUnit 4的@BeforeClass。这样的方法会被继承(除非它们被隐藏 或覆盖),并且它必须是 static方法(除非”per-class” 测试实例生命周期 被使用)

@AfterAll

表示使用了该注解的方法应该在当前类中所有使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之后执行;类似于JUnit 4的@AfterClass。这样的方法会被继承(除非它们被隐藏 或覆盖),并且它必须是 static方法(除非”per-class” 测试实例生命周期 被使用)。

@Nested

表示使用了该注解的类是一个内嵌、非静态的测试类。@BeforeAll和@AfterAll方法不能直接在@Nested测试类中使用,(除非”per-class” 测试实例生命周期 被使用)。

@Tag

用于声明过滤测试的tags,该注解可以用在方法或类上;类似于TesgNG的测试组或JUnit4的分类。该注解能被继承,但仅限于类级别,而非方法级别。

@Disable

用于禁用一个测试类或测试方法;类似于JUnit4的@Ignore。

@Timeout

如果其执行超过一个给定的持续时间,失败测试用例。

@ExtendWith

用于以申明方法注册自定义扩展。

@RegisterExtension

通过字段用于以编程方式注册自定义扩展。

@TempDir

用于提供一个临时目录通过字段注入或参数注入生命周期方法或试验方法;位于org.junit.jupiter.api.io包。

自定义注解

我们可以定义自己的组合注解,而自定义的组合注解会自动继承其元注解的语义。此处已官方Demo为例。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Tag;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("fast")
public @interface FastTag {
    
}

通过这种方式,我们实现了一个与@Tag(“fast”)等价的自动定义注解@FastTag。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值