关于云计算:JUnit5学习之五标签Tag和自定义注解

83次阅读

共计 6902 个字符,预计需要花费 18 分钟才能阅读完成。

欢送拜访我的 GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,波及 Java、Docker、Kubernetes、DevOPS 等;

对于《JUnit5 学习》系列

《JUnit5 学习》系列旨在通过实战晋升 SpringBoot 环境下的单元测试技能,一共八篇文章,链接如下:

  1. 基本操作
  2. Assumptions 类
  3. Assertions 类
  4. 按条件执行
  5. 标签 (Tag) 和自定义注解
  6. 参数化测试 (Parameterized Tests) 根底
  7. 参数化测试 (Parameterized Tests) 进阶
  8. 综合进阶(终篇)

本篇概览

本文是《JUnit5 学习》系列的第五篇,一起来学习 JUnit5 的标签 (Tag) 性能,构想一个工程中的有很多测试类和测试方法,有的场景只需执行其中一部分测试方法,如何实现呢?此时 Junit 的标签性能就派上用场了,咱们能够按须要给测试类或者办法打标签,在执行单元测试时依照标签进行过滤,学完了标签再来理解 JUnit5 对自定义注解的反对状况,本篇纲要如下:

  1. 设置标签
  2. 在 IDEA 中做标签过滤
  3. 用 maven 命令时做标签过滤
  4. 用 surefire 插件时做标签过滤
  5. 标签表达式
  6. 自定义注解
  7. 更加简化的自定义注解
  8. 标签命名标准

源码下载

  1. 如果您不想编码,能够在 GitHub 下载所有源码,地址和链接信息如下表所示:
名称 链接 备注
我的项目主页 https://github.com/zq2599/blo… 该我的项目在 GitHub 上的主页
git 仓库地址(https) https://github.com/zq2599/blo… 该我的项目源码的仓库地址,https 协定
git 仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该我的项目源码的仓库地址,ssh 协定
  1. 这个 git 我的项目中有多个文件夹,本章的利用在 <font color=”blue”>junitpractice</font> 文件夹下,如下图红框所示:

  1. <font color=”blue”>junitpractice</font> 是父子构造的工程,本篇的代码在 <font color=”red”>tag</font> 子工程中,如下图:

设置标签

  1. 在父工程 <font color=”blue”>junitpractice</font> 里新建名为 <font color=”blue”>tag</font> 的子工程,明天的单元测试代码都写在这个 tag 工程中;
  2. 一共写两个测试类,第一个 FirstTest.java 如下,可见类上有 Tag 注解,值为 <font color=”blue”>first</font>,另外每个办法上都有 Tag 注解,其中 <font color=”blue”>first1Test</font> 办法有两个 Tag 注解:
package com.bolingcavalry.tag.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
@Slf4j
@Tag("first")
public class FirstTest {

    @Test
    @Tag("easy")
    @Tag("important")
    @DisplayName("first-1")
    void first1Test() {log.info("first1Test");
        assertEquals(2, Math.addExact(1, 1));
    }

    @Test
    @Tag("easy")
    @DisplayName("first-2")
    void first2Test() {log.info("first2Test");
        assertEquals(2, Math.addExact(1, 1));
    }

    @Test
    @Tag("hard")
    @DisplayName("first-3")
    void first3Test() {log.info("first3Test");
        assertEquals(2, Math.addExact(1, 1));
    }
}
  1. 第二个测试类 SecondTest.java,也是类和办法都有 Tag 注解:
package com.bolingcavalry.tag.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
@Slf4j
@Tag("second")
public class SecondTest {

    @Test
    @Tag("easy")
    @DisplayName("second-1")
    void second1Test() {log.info("second1Test");
        assertEquals(2, Math.addExact(1, 1));
    }

    @Test
    @Tag("easy")
    @DisplayName("second-2")
    void second2Test() {log.info("second2Test");
        assertEquals(2, Math.addExact(1, 1));
    }

    @Test
    @Tag("hard")
    @Tag("important")
    @DisplayName("second-3")
    void second3Test() {log.info("second3Test");
        assertEquals(2, Math.addExact(1, 1));
    }
}
  • 以上就是打好了标签的测试类和测试方法了,接下来看看如何通过这些标签对测试方法进行过滤,执行单元测试有三种罕用形式,咱们挨个尝试每种形式如何用标签过滤;

在 IDEA 中做标签过滤

  1. 如下图所示,点击红框中的 <font color=”blue”>Edit Configurations…</font>:

  1. 如下图红框,在弹出的窗口上新增一个 JUnit 配置:

  1. 接下来的操作如下图所示,<font color=”blue”>Test kind</font> 抉择 <font color=”red”>Tags</font>,就会依照标签过滤测试方法,<font color=”blue”>Tag expression</font> 外面填写过滤规定,前面会具体解说这个规定,这里先填个已存在的标签 <font color=”red”>important</font>:

  1. 创立好 JUnit 配置后,执行下图红框中的操作即可执行单元测试:

  1. 执行后果如下,所有打了 <font color=”blue”>important</font> 标签的测试方法被执行:

用 maven 命令时做标签过滤

  1. 前面试过 IDEA 上按标签过滤测试方法,其实用 maven 命令执行单元测试的时候也能按标签来过滤,接下来试试;
  2. 在父工程 <font color=”blue”>junitpractice</font> 的 pom.xml 所在目录下,执行以下命令,即可开始单元测试,并且只执行带有标签的办法:
mvn clean test -Dgroups="important"
  1. 执行结束后后果如下:

  1. 翻看日志,可见只有打了 important 标签的测试方法被执行了,如下图红框所示:

  1. 再看看其余子工程的执行状况,用前一篇文章里的 conditional 为例,可见没有任何测试方法被执行,如下图红框所示:

  1. 再去看看 surefire 插件给出的测试报告,报告文件在 <font color=”blue”>junitpractice\tag\target\surefire-reports</font> 目录下,下图红框中的文件就是测试报告:

  1. 关上上图红框中的一个文件,如下图红框,可见只有打了 <font color=”blue”>important</font> 标签的测试方法被执行了:

  • 以上就是 maven 命令执行单元测试时应用标签过滤的办法,接下来试试在应用 maven-surefire-plugin 插件时如何通过做标签过滤

用 surefire 插件时做标签过滤

  1. surefire 是个测试引擎(TestEngine),以 maven 插件的形式来应用,关上 tag 子工程的 pom.xml 文件,将 build 节点配置成以下模式,可见 groups 就是标签过滤节点,另外 <font color=”blue”>excludedGroups</font> 节点制订的 hard 标签的测试方法不会执行:
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <!-- 要执行的标签 -->
                    <groups>important</groups>
                    <!-- 不要执行的标签 -->
                    <excludedGroups>hard</excludedGroups>
                </configuration>
            </plugin>
        </plugins>
    </build>
  1. 在 tag 子工程的 pom.xml 所在目录,执行命令 <font color=”blue”>mvn clean test</font> 即可开始单元测试,后果如下,可见打了 important 标签的 first1Test 被执行,而 second3Test 办法只管有 important 标签,然而因为其 hard 标签曾经被设置为不执行,因而 second3Test 没有被执行:

标签表达式

  1. 后面咱们用三种办法执行了单元测试,每次都是用 important 标签过滤,其实除了指定标签,JUnit 还反对更简单的标签过滤,即标签表达式
  2. 所谓标签表达式,就是用 ” 非 ”、” 与 ”、” 或 ” 这三种操作符将更多的标签连接起来,实现更简单的过滤逻辑;
  3. 上述三种操作符的定义和用法如下表:
操作符 作用 举例 举例说明
& important & easy 既有 important,又有 easy 标签,
在本文是 first1Test
! important & !easy 有 important,同时又没有 easy 标签,
在本文是 second3Test
\ important \ hard 有 important 标签的,再加上有 hard 标签的,
在本文是 first1Test、first3Test、second3Test
  1. 试试标签表达式的成果,如下图红框,批改后面创立好的 IDEA 配置,从之前的 <font color=”blue”>important</font> 改为 <font color=”red”>important | hard</font>:

  1. 再次执行这个配置,后果如下图红框所示,只有这三个办法被执行:first1Test、first3Test、second3Test,可见标签表达式失效了:

  1. 在 maven 命令和 surefire 插件中应用标签表达式的操作就不在文中执行了,请您自行验证;

自定义注解

  1. JUnit 反对自定义注解,先回顾之前的代码,看咱们是如何给办法打标签的,以 first3Test 办法为例:
    @Test
    @Tag("hard")
    @DisplayName("first-3")
    void first3Test() {log.info("first3Test");
        assertEquals(2, Math.addExact(1, 1));
    }
  1. 接下来咱们创立一个注解,将 <font color=”blue”>@Tag(“hard”)</font> 替换掉,新注解的源码如下,可见仅是一个一般的注解定义:
package com.bolingcavalry.tag.service.impl;

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

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Tag("hard")
public @interface Hard {}
  1. 批改 first3Test 办法的注解,去掉 <font color=”blue”>@Tag(“hard”)</font>,改为 <font color=”red”>@Hard</font>:
    @Test
    @Hard
    @DisplayName("first-3")
    void first3Test() {log.info("first3Test");
        assertEquals(2, Math.addExact(1, 1));
    }
  1. 执行后面创立的 <font color=”blue”>tag-important</font> 配置,可见 hard 标签的过滤仍旧无效:

更加简化的自定义注解

  1. 上述 Hard 注解取代了 <font color=”blue”>@Tag(“hard”)</font>,其实还能够更进一步对已有注解做简化,上面是个新的注解:HardTest.java,和 Hard.java 相比,多了个 <font color=”blue”>@Test</font>,作用是集成了 Test 注解的能力
package com.bolingcavalry.tag.service.impl;

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

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Tag("hard")
@Test
public @interface HardTest {}
  1. 于是,<font color=”blue”>first3Test</font> 办法的注解能够改成上面的成果,可见 Test 和 Tag 注解都去掉了:
    @HardTest
    @DisplayName("first-3")
    void first3Test() {log.info("first3Test");
        assertEquals(2, Math.addExact(1, 1));
    }
  1. 执行后面创立的 <font color=”blue”>tag-important</font> 配置,可见 hard 标签的过滤仍旧无效:

标签命名标准

最初一起来看看给标签取名时有哪些要留神的中央:

  1. 标签名左右两侧的空格是有效的,执行测试的时候会做 trim 解决,例如上面这个标签会被当作 <font color=”blue”>hard</font> 来过滤:

  1. 标签名不能有这六个符号 <font color=”blue”>,() & | !</font>
  • 至此,JUnit5 的标签过滤和自定义注解性能都学习实现了,有了这些能力,咱们能够更加灵便和得心应手的应酬不同的场景和需要;

你不孤独,欣宸原创一路相伴

  1. Java 系列
  2. Spring 系列
  3. Docker 系列
  4. kubernetes 系列
  5. 数据库 + 中间件系列
  6. DevOps 系列

欢送关注公众号:程序员欣宸

微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游 Java 世界 …
https://github.com/zq2599/blog_demos

正文完
 0