Junit 扩展-ApiHug准备-测试篇-012

   🤗 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 更深内容 Extension Modelopen in new window;

在 Junit4 中有, Runner, TestRule, & MethodRule 扩展点, 在Junit 5中归一为 API Extension , 不过这也仅仅是个 marker interface。

Spring Test Junit4 Extenstionopen in new window vs Spring Test Jupiter Extenstionopen in new window, 两个正好体现 Junit 4&5 之间的差别。

Junit4 的扩展局限性:

  1. 必须在测试类级别上使用 @RunWith 注解来声明 Runner 。
  2. @RunWith 仅接受一个参数: Runner 的实现类。因为每个测试类最多只能拥有一个 Runner ,所以每个测试类最多也只能拥有一个扩展点。(在PowerMock中引入了 @PowerMockRunnerDelegate,可以同时使用两个Runner)
  3. 为了解决 Runner 的限制,JUnit 4.7 引入了 @Rule 。一个测试类可声明多个 @Rule ,这些规则可在类级别和测试方法级别上运行,但是它只能在测试运行之前或之后执行指定操作。如果我们想在此之外的时间点进行扩展,@Rule也无法满足我们的要求。

JUnit 5扩展机制的核心准则: Prefer extension points over features; 基于这一准则,JUnit 5 中定义了许多扩展点,每个扩展点都对应一个接口。我们可以定义自己的扩展可以实现其中的某些接口,然后通过 @ExtendWith 注解注册给 JUnit,后者会在特定的时间点调用注册的接口实现。

JUnit5 定义的部分扩展点:

接口说明
BeforeAllCallback在所有测试方法执行前定义测试容器执行的行为,也就是在 @BeforeAll 注解的方法之前执行
AfterAllCallback在@AfterAll 注解的方法之后执行
BeforeEachCallback在@BeforeEach 注解的方法之前执行
AfterEachCallback在@AfterEach 注解的方法之后执行
BeforeTestExecutionCallback在测试方法运行之前立刻执行
AfterTestExecutionCallback在测试方法运行之后立刻执行
ParameterResolver用于在运行时动态解析参数

Extension Context

Extension Context包含了测试方法的上下文信息,所有的扩展接口都定义了一个包含该参数的接口方法,开发者可以根据Extension Context拿到跟测试方法相关的几乎所有的信息,包括方法注解,测试实例,测试标签等。

Store

Extension Context 提供了一个getStore(Namespace namespace)的接口方法,返回了一个Store的对象,用于存储一些数据,方便不同的回调接口之间共享数据。

Namespace

如果你需要使用Extension Context里的Store功能,那么你就需要先申请一个Namespace,它可以避免不同的扩展实现误操作同一份数据

#统计执行时间

extensions>benchmarkopen in new window 例子:


class BenchmarkExtensionimplements BeforeAllCallback,BeforeTestExecutionCallback,AfterTestExecutionCallback,AfterAllCallback {}

BenchmarkExtension 定义扩展点:

  1. 计算所有测试类的运行时间,在所有测试执行前保存其起始时间
  2. 计算每个测试方法的运行时间,在每个测试方法执行前保存其起始时间
  3. 在每个测试方法执行完毕后,获取其结束时间,计算并输出该测试方法的运行时间
  4. 在所有测试类执行完毕后,获取其结束时间,计算并输出所有测试的运行时间
  5. 对所有注解了 @BenchMark 的测试类或测试方法生效

定义 @Benchmark


@Target({ TYPE, METHOD, ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(BenchmarkExtension.class)
public @interface Benchmark { }

测试类:


@Benchmark
public class BenchmarkTest {@Test@Benchmarkpublic void test_1() {try {Thread.sleep(2_000);} catch (InterruptedException e) {e.printStackTrace();}}@Testpublic void test_2() {try {Thread.sleep(1_000);} catch (InterruptedException e) {e.printStackTrace();}}
}

获得测试输出:


Test 'test_1()' took 2033 ms.
Test container 'BenchmarkTest' took 2115 ms.

#Test Watcher

TestWatcheropen in new window 接口定义了API扩展,提供钩子函数对测试处理结果进行进一步的处理。

比如不同过的测试状态: testDisabled testSuccessful 等等。

public class TestResultLoggerExtension implements TestWatcher, AfterAllCallback {}

测试用例:

@ExtendWith(TestResultLoggerExtension.class)
class TestWatcherAPIUnitTest {
}

测试输出


Test Disabled for test givenFailure_whenTestDisabledWithReason_ThenCaptureResult(): with reason :- This test is disabled
....
Test result summary for TestWatcherAPIUnitTest {ABORTED=1, SUCCESSFUL=1, DISABLED=2}

#Parameter Resolver

我们对 @Random 标注参数, 从上下文注入随机参数 junit5-jupiter-extensions>randomopen in new window:

public class RandomParametersExtension implements ParameterResolver {@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.PARAMETER)public @interface Random {}@Overridepublic boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {return parameterContext.isAnnotated(Random.class);}@Overridepublic Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {return getRandomValue(parameterContext.getParameter(), extensionContext);}private Object getRandomValue(Parameter parameter, ExtensionContext extensionContext) {Class<?> type = parameter.getType();java.util.Random random =extensionContext.getRoot().getStore(Namespace.GLOBAL) //.getOrComputeIfAbsent(java.util.Random.class);if (int.class.equals(type)) {return random.nextInt();}if (double.class.equals(type)) {return random.nextDouble();}throw new ParameterResolutionException("No random generator implemented for " + type);}
}

测试用例:

@ExtendWith(RandomParametersExtension.class)
class RandomParametersExtensionTests {@Testvoid injectsInteger(@Random int i, @Random int j) {assertNotEquals(i, j);}@Testvoid injectsDouble(@Random double d) {assertEquals(0.0, d, 1.0);}
}

#参考

  1. 更复杂关于Datasource上下文的扩展

我们

api-hug-contact

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

告别轮询,SSE 流式传输可太香了!

嗨&#xff01;我是小谷&#xff0c;大家好久不见~ 今天想和大家分享的一个技术是 SSE 流式传输。如标题所言&#xff0c;通过 SSE 流式传输的方式可以让我们不再通过轮询的方式获取服务端返回的结果&#xff0c;进而提升前端页面的性能。对于需要轮询的业务场景来说&#xff…

【Linux 杂货铺】进程间通信

1.进程为什么要通信呢&#xff1f; ①&#x1f34e; 为了进程之间更好的协同工作&#xff0c;举个例子&#xff0c;在学校&#xff0c;学院的管理人员给教师安排课程的时候&#xff0c;必须事先知道该教师平常的上课情况&#xff0c;不然会将教师的课程安排到一起造成麻烦&…

安装mathutils方法

使用blenderproc的时候&#xff0c;需要安装mathutils&#xff0c;但是直接pip会出现问题&#xff0c;这里记录一下如何安装。 官方安装方法 这里是mathutils的库&#xff0c;里面写了安装方式&#xff1a; mathutils 3.3.0 on PyPI - Libraries.io git clone https://gitl…

【GIS教程】ArcGIS做日照分析(附练习数据下载)

我国对住宅日照标准的规定是:冬至日住宅底层日照不少于1小时或大寒日住宅层日照不少于2小时(通常以当地冬至日正午12时的太阳高度角作为依据)。因冬至日太阳高度角最低&#xff0c;照射范围最小&#xff0c;如果冬至日12&#xff1a;00建筑物底层能够接收到阳光&#xff0c;那么…

记录一个hive中跑insert语句说没创建spark客户端的问题

【背景说明】 我目前搭建离线数仓&#xff0c;并将hive的执行引擎改成了Spark&#xff0c;在将ods层的数据装载到dim层&#xff0c;执行insert语句时报如下错误 【报错】 [42000][40000] Error while compiling statement: FAILED: SemanticException Failed to get a spark…

一文学会 ts 构建工具 —— tsup

文章目录 能打包什么&#xff1f;安装用法自定义配置文件条件配置在 package.json 中配置多入口打包生成类型声明文件sourcemap生成格式自定义输出文件代码分割产物目标环境支持 es5编译的环境变量对开发命令行工具友好监听模式 watch提供成功构建的钩子 onSuccess压缩产物 min…

史上最全的四分之一、半车再到全车7自由度常规悬架建模与仿真之一

一、悬架建模的简化过程 汽车是一个复杂的振动系统&#xff0c;针对不同的需求进行不同的简化。在对悬架振动分析中&#xff0c;把汽车车身看做一个刚体&#xff0c;把驾驶员座椅和驾驶员拿掉&#xff1b;车身以下至车轮之间的橡胶垫&#xff0c;连接杆&#xff0c;弹簧等具有…

Veritas Backup Exec 23.0 (Windows) - 面向中小型企业的数据备份和恢复

Veritas Backup Exec 23.0 (Windows) - 面向中小型企业的数据备份和恢复 请访问原文链接&#xff1a;Veritas Backup Exec 23.0 (Windows) - 面向中小型企业的数据备份和恢复&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Ba…

线性代数基础2矩阵

矩阵是什么 矩阵就是二维数组&#xff0c;下面是一个 m 乘 n 的矩阵&#xff0c;它有 m 行&#xff0c;n 列&#xff0c;每行每列上面都有元素&#xff0c;每个元素都有行标i 和列标 j&#xff0c; a ij 。简称m n矩阵&#xff0c;记作&#xff1a; 注意a11的索引是 A[0,0]。…

leetcode:438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s "cbaebabacd", p "…

使用Python爬取易车网汽车信息(含x-sign参数逆向分析)

文章目录 1. 写在前面2. 接口分析3. 断点分析3. 算法还原 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致…

Java如何实现List的反转

hi&#xff0c;我是程序员王也&#xff0c;一个资深Java开发工程师&#xff0c;平时十分热衷于技术副业变现和各种搞钱项目的程序员~&#xff0c;如果你也是&#xff0c;可以一起交流交流。 今天我们来聊聊Java中实现List反转~ List反转的基本概念 在Java中&#xff0c;反转一…