前言

上一节介绍了基于 junit4 实现 junitperf,但是可以发现定义变量的方式依然不够优雅。

那可以让用户使用起来更加自然一些吗?

有的,junit5 为我们带来了更加强大的功能。

拓展阅读:

浅谈性能测试

基于 junit4 分析 junitperf 源码,junit4 99% 的人都不知道的秘密!

没有对比,就没有伤害

我们首先回顾一下 junit4 的写法:

public class HelloWorldTest {

    @Rule
public JunitPerfRule junitPerfRule = new JunitPerfRule(); /**
* 单一线程,执行 1000ms,默认以 html 输出测试结果
* @throws InterruptedException if any
*/
@Test
@JunitPerfConfig(duration = 1000)
public void helloWorldTest() throws InterruptedException {
System.out.println("hello world");
Thread.sleep(20);
} }

再看一下 junit5 的写法:

public class HelloWorldTest {

    @JunitPerfConfig(duration = 1000)
public void helloTest() throws InterruptedException {
Thread.sleep(100);
System.out.println("Hello Junit5");
} }

JunitPerfRule 竟然神奇的消失了?这一切是怎么做到的呢?

让我们一起揭开 junit5 神秘的面纱。

Junit5 更加强大的特性

@JunitPerfConfig

我们只是指定了一个简单的 @JunitPerfConfig 注解,那么问题一定就出在这个注解里。

定义如下:

import java.lang.annotation.*;

/**
* 执行接口
* 对于每一个测试方法的条件配置
* @author bbhou
* @version 1.0.0
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) @ExtendWith(PerfConfigProvider.class)
@TestTemplate
public @interface JunitPerfConfig { // 属性省略 }

@Retention 和 @Target 属于 java 中的常规注解,此处不做赘述。

我们重点看一下剩余的两个注解。

@TestTemplate

我们以前在写单元测试的时候,都会写一个 @Test 注解,你会发现 junit5 中连这个注解都省略了。

那么,他去哪里了呢?

答案就是 @TestTemplate 声明的注解,就是用来标识这个方法是单元测试的方法,idea 也会认的,这一点非常的灵活强大。

@ExtendWith

这个注解,给我们的注解进行了赋能。

看名字,就是一个拓展,拓展的实现,就是我们指定的类 PerfConfigProvider

PerfConfigProvider

我们来看一下 PerfConfigProvider 的实现。

public class PerfConfigProvider implements TestTemplateInvocationContextProvider {

    @Override
public boolean supportsTestTemplate(ExtensionContext context) {
return context.getTestMethod()
.filter(m -> AnnotationSupport.isAnnotated(m, JunitPerfConfig.class))
.isPresent();
} @Override
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
return Stream.of(new PerfConfigContext(context));
} }

实现非常简单,首先是一个过滤。

只有定义了 @JunitPerfConfig 注解的方法,才会生效。

下面就是我们自定义实现的上下文 PerfConfigContext。

PerfConfigContext

PerfConfigContext 实现了 TestTemplateInvocationContext,并且对原生的 ExtensionContext 进行了简单的封装。

public class PerfConfigContext implements TestTemplateInvocationContext {

    // 省略内部属性

    @Override
public List<Extension> getAdditionalExtensions() {
return Collections.singletonList(
(TestInstancePostProcessor) (testInstance, context) -> {
final Class clazz = testInstance.getClass();
// Group test contexts by test class
ACTIVE_CONTEXTS.putIfAbsent(clazz, new ArrayList<>()); EvaluationContext evaluationContext = new EvaluationContext(testInstance,
method,
DateUtil.getCurrentDateTimeStr());
evaluationContext.loadConfig(perfConfig);
evaluationContext.loadRequire(perfRequire);
StatisticsCalculator statisticsCalculator = perfConfig.statistics().newInstance();
Set<Reporter> reporterSet = getReporterSet();
ACTIVE_CONTEXTS.get(clazz).add(evaluationContext);
try {
new PerformanceEvaluationStatement(evaluationContext,
statisticsCalculator,
reporterSet,
ACTIVE_CONTEXTS.get(clazz),
clazz).evaluate();
} catch (Throwable throwable) {
throw new JunitPerfRuntimeException(throwable);
}
}
);
}
}

写到这里,我们就会发现又回到了和 junit4 相似的地方。

不明白的小伙伴可以去看一下原来的实现,这里不做赘述。

剩下的部分,和原来 junit4 的实现都是一致的。

小结

可以发现 junit5 为我们提供的拓展能力更加强大灵活,他可以让我们定义属于自己的注解。

这个注解用起来让用户和使用原有的 junit5 注解没有什么区别。

不得不感慨一句,长江后浪推前浪,前浪死在沙滩上。

参考资料

https://github.com/houbb/junitperf

https://github.com/junit-team/junit4/wiki/Rules

基于 junit5 实现 junitperf 源码分析的更多相关文章

  1. Django——基于类的视图源码分析 二

    源码分析 抽象类和常用视图(base.py) 这个文件包含视图的顶级抽象类(View),基于模板的工具类(TemplateResponseMixin),模板视图(TemplateView)和重定向视图 ...

  2. SPI机制剖析——基于DriverManager+ServiceLoader的源码分析

    我的上一篇博客类加载器与双亲委派中提到,SPI机制是一种上级类加载器调用下级类加载器的情形,因此会打破类加载的双亲委派模型.为了深入理解其中的细节,本博客详细剖析一下SPI机制,并以JDBC为例,基于 ...

  3. Django——基于类的视图源码分析 一

    基于类的视图(Class-based view)是Django 1.3引入的新的视图编写方式,用于取代以前基于函数(Function-based)方式. 借助于OO和Python中方便的多重继承特性, ...

  4. Django——基于类的视图源码分析 三

    列表类通用视图(list.py) 此文件包含用于显示数据列表常用的类和工具类.不仅可以方便的用于显示基于模型(Model)的数据列表,也可以用于显示自定义数据列表. 此图中绿色部分属于base.py, ...

  5. documentsUI源码分析

    documentsUI源码分析 本文基于Android 6.0的源码,来分析documentsUI模块. 原本基于7.1源码看了两天,但是Android 7.1与6.0中documentsUI模块差异 ...

  6. Spark大师之路:广播变量(Broadcast)源码分析

    概述 最近工作上忙死了……广播变量这一块其实早就看过了,一直没有贴出来. 本文基于Spark 1.0源码分析,主要探讨广播变量的初始化.创建.读取以及清除. 类关系 BroadcastManager类 ...

  7. 第八篇:Spark SQL Catalyst源码分析之UDF

    /** Spark SQL源码分析系列文章*/ 在SQL的世界里,除了官方提供的常用的处理函数之外,一般都会提供可扩展的对外自定义函数接口,这已经成为一种事实的标准. 在前面Spark SQL源码分析 ...

  8. HashMap源码分析(一)

    基于JDK1.7 HashMap源码分析 概述 HashMap是存放键值对的集合,数据结构如下: table被称为桶,大小(capacity)始终为2的幂,当发生扩容时,map容量扩大为两倍 Hash ...

  9. java集合源码分析(六):HashMap

    概述 HashMap 是 Map 接口下一个线程不安全的,基于哈希表的实现类.由于他解决哈希冲突的方式是分离链表法,也就是拉链法,因此他的数据结构是数组+链表,在 JDK8 以后,当哈希冲突严重时,H ...

  10. docker 源码分析 一(基于1.8.2版本),docker daemon启动过程;

    最近在研究golang,也学习一下比较火的开源项目docker的源代码,国内比较出名的docker源码分析是孙宏亮大牛写的一系列文章,但是基于的docker版本有点老:索性自己就git 了一下最新的代 ...

随机推荐

  1. 【C++】类大小

    [来源]C++类大小详尽讲解 [来源]空类(empty class)

  2. Linux-远程连接-ssh

  3. 【中介者模式(Mediator)】使用Java实现中介者模式

    引言 中介者,何为中介者,顾名思义就是我们的在处理A和B之间的关系的时候,引入一个中间人,来处理这两者之间的关系,例如生活中我们需要去租房,买房,都会有中介,来处理房东和租客之间的协调关系,这个就是中 ...

  4. [转帖]nginx源码层面探究request_time、upstream_response_time、upstream_connect_time与upstream_header_time指标具体含义与区别

    https://www.cnblogs.com/AcAc-t/p/nginx_request_time_upstream_respone_time_analysis.html 背景概述 最近计划着重分 ...

  5. [转帖]精通awk系列(19):awk流程控制之break、continue、next、nextfile、exit语句

    https://www.cnblogs.com/f-ck-need-u/   回到: Linux系列文章 Shell系列文章 Awk系列文章 break和continue break可退出for.wh ...

  6. java 调优需要关闭的组建

  7. elementui 的tabs组件出现蓝色边框问题

    elementui 的tabs组件出现蓝色边框问题 /deep/ .el-tabs__item:focus.is-active.is-focus:not(:active) { -webkit-box- ...

  8. 【分享代码片段】terraform中,如何从刚刚创建的 deployment 中获得所有容器的名字和 ip

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 不好意思,刚刚才开始用 terraform,或许是更好的办 ...

  9. 使用emmylua调试slua

    使用emmylua调试slua的方法 在lua的入口中加上emmylua的debug代码 在slua的LuaState.loaderDelegate委托中,添加判断如果是load_file_name= ...

  10. 小白学k8s(11)-k8s中Secret理解

    理解Secret 什么是Secret Secret的类型 Opaque Secret Opaque Secret的使用 将Secret挂载到Volume中 挂载的Secret会被自动更新 将Secre ...