Junit 基础-ApiHug准备-测试篇-009

     🤗 ApiHug × {Postman|Swagger|Api...} = 快↑ 准√ 省↓

  1. GitHub - apihug/apihug.com: All abou the Apihug   
  2. apihug.com: 有爱,有温度,有质量,有信任
  3. ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace

注解

JUnit5常用注:

  1. @Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
  2. @ParameterizedTest :表示方法是参数化测试,下方会有详细介绍
  3. @RepeatedTest :表示方法可重复执行,下方会有详细介绍
  4. @DisplayName :为测试类或者测试方法设置展示名称
  5. @BeforeEach :表示在每个单元测试之前执行
  6. @AfterEach :表示在每个单元测试之后执行
  7. @BeforeAll :表示在所有单元测试之前执行
  8. @AfterAll :表示在所有单元测试之后执行
  9. @Tag :表示单元测试类别,类似于JUnit4中的@Categories
  10. @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
  11. @Timeout :表示测试方法运行如果超过了指定时间将会返回错误
  12. @ExtendWith :为测试类或测试方法提供扩展类引用

JUnit5 和 Junit4 的变化:

说明Junit 4Junit 5
定义测试方法即用例@Test@Test
在当前类中的所有测试方法之前执行@BeforeClass@BeforeAll
在当前类中的所有测试方法之后执行@AfterClass@AfterAll
在每个测试用例前执行@Before@BeforeEach
在每个测试用例后执行@After@AfterEach
禁用测试方法或类@Ignore@Disabled
Tagging 和 filtering@Category@Tag

#实战

看下这个例子:


 @BeforeAll
  public static void init() {
    System.out.println("初始化数据");
  }

  @AfterAll
  public static void cleanup() {
    System.out.println("清理数据");
  }

  @BeforeEach
  public void tearup() {
    System.out.println("当前测试方法开始");
  }

  @AfterEach
  public void tearDown() {
    System.out.println("当前测试方法结束");
  }

然后再我们的每个测试例子我们看到这样的输出:


初始化数据
当前测试方法开始
当前测试方法结束
当前测试方法开始
我的第二个测试开始测试
当前测试方法结束
当前测试方法开始
我的第一个测试开始测试
当前测试方法结束
当前测试方法开始
当前测试方法结束

#Fixture

Test Fixture 是指一个测试运行所需的固定环境,准确的定义:

The test fixture is everything we need to have in place to exercise the SUT

在进行测试时,我们通常需要把环境设置成已知状态(如创建对象、获取资源等)来创建测试,每次测试开始时都处于一个固定的初始状态;

测试结果后需要将测试状态还原,所以,测试执行所需要的固定环境称为 Test Fixture。

细细分析下这个例子, 代码中使用到的一对注解 @BeforeAll 和 @AfterAll ,它们定义了整个测试类在开始前以及结束时的操作,只能修饰静态方法,主要用于在测试过程中所需要的全局数据和外部资源的初始化和清理。

与它们不同,@BeforeEach 和 @AfterEach 所标注的方法会在每个测试用例方法开始前和结束时执行,主要是负责该测试用例所需要的运行环境的准备和销毁, 也就是 fixture 的管理。

官方的例子open in new window 有非常详尽的描述。

#禁用

禁用执行测试:@Disabled

当我们希望在运行测试类时,跳过某个测试方法,正常运行其他测试用例时,我们就可以用上 @Disabled 注解,表明该测试方法处于不可用,执行测试类的测试方法时不会被 JUnit 执行。

下面看下使用 @Disbaled 之后的运行效果,在原来测试类中添加如下代码:



  @DisplayName("我的第三个测试")
  @Disabled
  @Test
  void testThirdTest() {
    System.out.println("我的第三个测试开始测试");
  }


都让 @Disabled 也可以使用在类上 也可以使用在类上面。

#内嵌

当我们编写的类和代码逐渐增多,随之而来的需要测试的对应测试类也会越来越多。

为了解决测试类数量爆炸的问题,JUnit 5提供了 @Nested 注解,能够以静态内部成员类的形式对测试用例类进行逻辑分组。

并且每个静态内部类都可以有自己的生命周期方法, 这些方法将按从外到内层次顺序执行。

此外,嵌套的类也可以用@DisplayName 标记,这样我们就可以使用正确的测试名称。下面看下简单的用法 NestUnitTestopen in new window:


@DisplayName("内嵌测试类")
public class NestUnitTest {

  @BeforeEach
  void init() {
    System.out.println("测试方法执行前准备");
  }

  @Nested
  @DisplayName("第一个内嵌测试类")
  class FirstNestTest {
    @Test
    void test() {
      System.out.println("第一个内嵌测试类执行测试");
    }
  }

  @Nested
  @DisplayName("第二个内嵌测试类")
  class SecondNestTest {
    @Test
    void test() {
      System.out.println("第二个内嵌测试类执行测试");
    }
  }
}

#重复

重复性测试:@RepeatedTest

在 JUnit 5 里新增了对测试方法设置运行次数的支持,允许让测试方法进行重复运行。

当要运行一个测试方法 N次时,可以使用 @RepeatedTest 标记它,如下面的代码所示 RepeatedUnitTestopen in new window:

@DisplayName("重复测试")
@RepeatedTest(value = 3)
public void i_am_a_repeated_test() {
	System.out.println("执行测试");
}

当然你也可以定制每次 的 DisplayName:


@DisplayName("自定义名称重复测试")
@RepeatedTest(value = 3, name = "{displayName} 第 {currentRepetition} 次")
public void i_am_a_repeated_test_2() {
	System.out.println("执行测试");
}

@RepeatedTest 注解内用 currentRepetition 变量表示已经重复的次数,totalRepetitions 变量表示总共要重复的次数,

displayName 变量表示测试方法显示名称,我们直接就可以使用这些内置的变量来重新定义测试方法重复运行时的名称。

#断言

在断言 API 设计上,JUnit 5 进行显著地改进,并且充分利用 Java 8 的新特性,特别是 Lambda 表达式,最终提供了新的断言类: org.junit.jupiter.api.Assertions 。

许多断言方法接受 Lambda 表达式参数,在断言消息使用 Lambda 表达式的一个优点就是它是 延迟计算 的,如果消息构造开销很大,这样做一定程度上可以节省时间和资源。

注意断言是 Assertions 和后面要介绍的 Assumptions (假设) 不太一样。

现在还可以将一个方法内的多个断言进行分组,使用 assertAll 方法如下示例代码 AppTestopen in new window:


@Test
  void groupAssertions() {
    int[] numbers = {0, 1, 2, 3, 4};
    assertAll(
        "numbers",
        () -> assertEquals(numbers[0], 0),
        () -> assertEquals(numbers[3], 3),
        () -> assertEquals(numbers[4], 4));
  }

如果分组断言中任一个断言的失败,都会将以 MultipleFailuresError 错误进行抛出提示。

还有很多:

  1. assertEquals
  2. assertNotEquals
  3. assertArrayEquals
  4. assertIterableEquals
  5. assertLinesMatch
  6. assertNotNull .....

比较有意思的两个: assertTimeout & assertThrows 具体示范下:

#assertTimeout

@Test
  @DisplayName("超时方法测试")
  void test_should_complete_in_one_second() {
    Assertions.assertTimeoutPreemptively(
        Duration.of(1, ChronoUnit.SECONDS), () -> Thread.sleep(900));
  }

这个测试运行失败,因为代码执行将休眠两秒钟,而我们期望测试用例在一秒钟之内成功

但是如果我们把休眠时间设置一秒钟,测试仍然会出现偶尔失败的情况,这是因为测试方法执行过程中除了目标代码还有额外的代码和指令执行会耗时,

所以在超时限制上无法做到对时间参数的完全精确匹配。

#assertThrows

我们代码中对于带有异常的方法通常都是使用 try-catch 方式捕获处理,针对测试这样带有异常抛出的代码,

而 JUnit 5 提供方法 Assertions#assertThrows(Class<T>, Executable) 来进行测试,第一个参数为异常类型,

第二个为函数式接口参数,跟 Runnable 接口相似,不需要参数,也没有返回,并且支持 Lambda 表达式方式使用,具体使用方式可参考下方代码:


@Test
void shouldThrowException() {
    Throwable exception =
        assertThrows(
            UnsupportedOperationException.class,
            () -> {
              throw new UnsupportedOperationException("Not supported");
            });
    assertEquals(exception.getMessage(), "Not supported");
}

#fail

fail()方法指未通过测试。 在尚未写的例子中可以用这个做个占位符!


@Test
  void testFailCase() {
    Assertions.fail(
        "as the method not implement this is a place hold to remind us, usually practice in the TDD");
    Assertions.fail(AppTest::message);
  }

  private static String message() {
    return "not found good reason to pass";
  }

#假设

JUnit 5假设类提供静态方法来支持基于假设的条件测试执行。假设失败会导致测试中止, 不会导致失败。

当继续执行给定的测试方法没有意义时,通常使用假设。在测试报告中,这些测试将被标记为通过

JUnit Assumptions(假设)类有以下方法:

  1. Assumptions.assumeTrue()
  2. Assumptions.assumeFalse()
  3. Assumptions.assumingThat()

AssumptionsTestExampleopen in new window 例子。

#assumeTrue/assumeFalse

  1. assumeTrue 该方法验证给定假设为真,如果假设为真,则测试继续进行,否则,测试执行将中止。
  2. assumeFalse 该方法验证给定假设为假,如果假设为假,则测试继续,否则,测试执行被中止。


  @Test
  void testOnDev() {
    System.setProperty("ENV", "DEV");
    assumeTrue("DEV".equals(System.getProperty("ENV")));
    System.out.println("测试继续执行...");
  }
  /** 测试失败,打印出失败消息 */
  @Test
  void testOnProd() {
    System.setProperty("ENV", "PROD");
    assumeTrue("DEV".equals(System.getProperty("ENV")), AssumptionsTestExample::message);
    System.out.println("测试不会继续执行,不会打印此行...");
  }

  private static String message() {
    return "测试失败...";
  }

#assumingThat

该方法执行提供的可执行上下文,但前提是提供的假设有效。与其他假设方法不同,此方法不会中止测试。

如果该假设无效,则该方法不起任何作用。

如果假设有效且可执行上下文抛出异常,则它将被视为常规测试失败。

抛出的异常将按原样重新抛出,但被掩盖为未经检查的异常。

@Test
  void testInAllEnvironments() {
    System.setProperty("ENV", "DEV");
    assumingThat(
        "DEV".equals(System.getProperty("ENV")),
        () -> {
          // 仅在DEV服务器上执行这些断言和打印
          // 即System.setProperty("ENV", "DEV")才会执行
          assertEquals(3, 1 + 2);
        });

    // 在所有环境中执行这些断言
    assertEquals(13, 6 + 7);
  }

我们

api-hug-contact

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32直接存储器存取DMA

前提知识&#xff1a; 1、STM32F103内部存储器结构以及映射 STM32F103的程序存储器、数据存储器、寄存器和IO端口被组织在同一个4GB的线性地址空间内。数据字节以小端模式存放在存储器中。即低地址中存放的是字数据的低字节&#xff0c;高地址中存放的是字数据的高字节 可访问…

React间接实现一个动态组件逻辑

在开发一个浏览器插件的时候&#xff0c;用的plasmo框架和react支持的&#xff0c;里面使用react开发一个菜单功能&#xff0c;但是又不想使用react-router&#xff0c;所以就想着能不能使用一个很简单的方式做一个替代方案&#xff1f;那肯定是可以。 我在引入一个组件后&…

C语言 | Leetcode C语言题解之第40题组合总和II

题目&#xff1a; 题解&#xff1a; int** ans; int* ansColumnSizes; int ansSize;int* sequence; int sequenceSize;int** freq; int freqSize;void dfs(int pos, int rest) {if (rest 0) {int* tmp malloc(sizeof(int) * sequenceSize);memcpy(tmp, sequence, sizeof(int…

Golang | Leetcode Golang题解之第37题解数独

题目&#xff1a; 题解&#xff1a; func solveSudoku(board [][]byte) {var line, column [9][9]boolvar block [3][3][9]boolvar spaces [][2]intfor i, row : range board {for j, b : range row {if b . {spaces append(spaces, [2]int{i, j})} else {digit : b - 1line…

如何实现外网访问内网ip?公网端口映射或内网映射来解决

本地搭建服务器应用&#xff0c;在局域网内可以访问&#xff0c;但在外网不能访问。如何实现外网访问内网ip&#xff1f;主要有两种方案&#xff1a;路由器端口映射和快解析内网映射。根据自己本地网络环境&#xff0c;结合是否有公网IP&#xff0c;是否有路由权限&#xff0c;…

Vast+产品展厅 | Vastbase G100数据库是什么架构?(1)

Vastbase G100是海量数据融合了多年对各行业应用场景的深入理解&#xff0c;基于openGauss内核开发的企业级关系型数据库。 了解Vastbase G100的架构&#xff0c;可以帮助您确保数据库系统的高效、可靠和安全运行。 “Vast产品展厅”将分两期&#xff0c;为您详细讲解Vastbas…

Excel模板导入、导出工具类

1.引入maven依赖&#xff0c;利用hutool的excel读取 Hutool-poi对excel读取、写入 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency> <depen…

手写Java设计模式之工厂模式,附源码解读

工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 工厂模式属于创建型…

智慧园区引领产业智能化升级:科技创新驱动打造智慧化、高效化产业新未来

随着全球科技革命的深入推进&#xff0c;以大数据、云计算、物联网、人工智能等为代表的新一代信息技术正深刻改变着传统产业的发展模式。在这一背景下&#xff0c;智慧园区作为产业智能化升级的重要载体和平台&#xff0c;正以其前瞻性的规划、创新的科技和卓越的实践&#xf…

桥接模式【结构型模式C++】

1.概述 桥接模式是一种结构型设计模式&#xff0c;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。 这种模式涉及到一个作为桥接的接口&am…

完整、免费的把pdf转word文档

在线工具网 https://www.orcc.online/pdf 支持pdf转word&#xff0c;免费、完整、快捷 登录网站 https://orcc.online/pdf 选择需要转换的pdf文件&#xff1a; 等待转换完成 点击蓝色文件即可下载 无限制&#xff0c;完整转换。

C语言-浮点数在内存中的存储

目录 C语言-浮点数在内存中的存储 练习 浮点数的存储 浮点数存的过程 浮点数在内存的存储 浮点数取的过程 C语言-浮点数在内存中的存储 常见的浮点数&#xff1a;3.14149、1E10&#xff08;科学计数法表示形式&#xff1a;1.0*10^10&#xff09;等&#xff0c;浮点数家族…

数据赋能(62)——要求:数据管理部门能力

“要求&#xff1a;数据管理部门能力”是作为标准的参考内容编写的。 在实施数据赋能中&#xff0c;数据管理部门的能力体现在多个方面&#xff0c;关键能力如下图所示。 在实施数据赋能的过程中&#xff0c;数据管理部门应具备的关键能力如下。 数据治理与标准化能力 数据管…

数字技术重塑园区管理,数字园区开启智慧化新篇章,引领产业创新发展

目录 一、引言 二、数字技术重塑园区管理 1、智能化基础设施建设 2、数据驱动的决策管理 3、精细化服务模式 三、数字园区开启智慧化新篇章 1、智慧化运营管理 2、智慧化产业创新 3、智慧化生态环境 四、引领产业创新发展 1、推动传统产业转型升级 2、培育新兴产业…

A Geolocation Databases Study(2011年)第五部分:Evalution Model

下载地址:A Geolocation Databases Study | IEEE Journals & Magazine | IEEE Xplore 被引次数:195 Shavitt Y, Zilberman N. A geolocation databases study[J]. IEEE Journal on Selected Areas in Communications, 2011, 29(10): 2044-2056. 5. Discussion 在我们讨…

JavaSE——常用API进阶二(6/8)-ZoneId、ZoneDateTime、Instant(常见方法、用法示例)

目录 ZoneId 常见方法 用法示例 ZoneDateTime 常见方法 用法示例 Instant 常见方法 用法示例 如果在开发中我们有这样的需求&#xff1a;我们的系统需要获取美国现在的时间&#xff0c;或者其他地区的时间给用户观看&#xff0c;或者进行一些处理&#xff0c;那应该怎…

企业常用Linux正则表达式与三剑客企业生产环境及知识/企业中远程连接ssh工具,需要一定的配置(为什么连接有时慢?)

企业高薪思维: 1.学习去抓重点有价值知识 2.猛劲学&#xff0c;使劲学&#xff08;能否给别人将会&#xff0c;讲明白&#xff0c;写明白&#xff0c;练习明白&#xff09;&#xff0c;在学习过程中你觉得学会了60-80%&#xff0c;其实你只会了40-50%&#xff0c;你要讲明白会操…

毅速3D打印随形透气钢:革新传统,引领未来

透气钢&#xff0c;这种多孔金属材料&#xff0c;既融合了金属材料的坚固性&#xff0c;又具备了透气材料的通透性。尤其在注塑模具的制造中&#xff0c;透气钢的作用不可忽视。通过镶嵌透气钢&#xff0c;能够有效解决因困气产生的注塑问题&#xff0c;使成型加工更为完善&…

【云计算】云数据中心网络(三):NAT 网关

《云网络》系列&#xff0c;共包含以下文章&#xff1a; 云网络是未来的网络基础设施云网络产品体系概述云数据中心网络&#xff08;一&#xff09;&#xff1a;VPC云数据中心网络&#xff08;二&#xff09;&#xff1a;弹性公网 IP云数据中心网络&#xff08;三&#xff09;…