Awaitility同步异步工具实战示例详解

目录
  • 引言
  • 1. awaitility入门
    • 1.1 静态导入
    • 1.2 简单例子
  • 2. awaitility在RocketMQ中的实战
  • 3. 总结

引言

在编写测试用例的时候遇到有异步或者队列处理的时候经常会用到 Thread.sleep() 等待来进行测试。例如:DLedger 测试选举的过程。当DLedger Leader下线。此时DLedger会重新发起选举,这个选举的过程是需要一定时间。很多时候在测试代码中就会使用 Thread.sleep 。

由于选举需要的时间多少不确定所以sleep时间就会设置为开发者经验的最大值。这样会造成测试代码会变得很慢。 当然开发者可以通过自己轮询来实现减少时间的消耗。

下面介绍一个处理这个一类问题的工具:awaitility

1. awaitility入门

Maven:

<dependency>
      <groupId>org.awaitility</groupId>
      <artifactId>awaitility</artifactId>
      <version>xxxx</version>
      <scope>test</scope>
</dependency>

文章编写的时候版本为:4.2.0

1.1 静态导入

为了有效地使用Awaitility,建议从Awaitility框架中静态地导入以下方法:

org.awaitility.Awaitility.*

在使用的时候需要搭配Java的时间相关的类以及Junit相关类:

java.time.Duration.*

java.util.concurrent.TimeUnit.*

org.junit.Assert.*

1.2 简单例子

例子1:

await().until(newUserIsAdded());

等待直到执行newUserIsAdded()返回true. 这个是没有返回值的。

例子2:

await().atMost(5, SECONDS).until(newUserWasAdded());

最多等待5秒,等待直到执行newUserIsAdded()返回true. 这个是没有返回值的。

例子3:

await().until( userRepositorySize(), equalTo(1) );

等待直到执行userRepositorySize()返回方法对应的值. 这个是有返回值

更多的例子可以参照官网 使用例子

2. awaitility在RocketMQ中的实战

在RocketMQ的test cases 中有一些使用了 Thread.sleep,接下来我们看看如何使用awaitility进行优化,减少测试用例的执行时间。以ControllerManagerTest测试用例为例子来解决,在代码中可以看到有这样的代码:

上图框出来的代码主要的作用是什么呢?等待Broker的Master过期,但是过期的时间我们根据设置的心跳的过期时间来预估时间。所以这里填写的是6秒当然你也可以填写10秒或者更长。

解决之前的执行时间:

使用awaitility对代码进行改造重构:

重构后的代码,如上图的红线框出来部分。当然我这里还对其他的进行处理。

有兴趣的可以关注一下RocketMQ的这个ISSUE:github.com/apache/rock…

使用awaitility重构后的执行时间:

时间有明显的下降。相比之前的下降了5秒左右。

3. 总结

  • 在测试过程中引入awaitility能够很大程度上方便测试,无需要每次都凭经验去预估时间。并且很多时候这个Thread.sleep的时间不是很好估算。减少了单元测试执行的时间。特别是像RocketMQ这样大型的项目单元测试很多。并且很多都是去测试分布式的,如果使用Thread.sleep会导致整个单元测试的时间很长。
  • 无需自己去实现轮询来减少单元测试的时间。

以上就是Awaitility同步异步工具实战示例详解的详细内容,更多关于Awaitility同步异步工具实的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java异步调用转同步方法实例详解

    先说一下对异步和同步的理解: 同步调用:调用方在调用过程中,持续等待返回结果. 异步调用:调用方在调用过程中,不直接等待返回结果,而是执行其他任务,结果返回形式通常为回调函数. 其实,两者的区别还是很明显的,这里也不再细说,我们主要来说一下Java如何将异步调用转为同步.换句话说,就是需要在异步 调用过程中,持续阻塞至获得调用结果. 不卖关子,先列出五种方法,然后一一举例说明: 使用wait和notify方法 使用条件锁 Future 使用CountDownLatch 使用CyclicBarri

  • java同步与异步的学习笔记整理

    概念: 1.同步:所有的操作都做完,才返回给用户.这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉).这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了. 2.异步:将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了.然后程序再慢慢地去写入数据库去.这就是异步.但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了.你可以关闭界面了. 同步,是所有的操作都做完,才返回给用户结果:即

  • 详解java 三种调用机制(同步、回调、异步)

    1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口 具体说来:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法, 实例1:使用java中Timer来在给定时间间隔发送通知,每隔十秒打印一次数据 Tim

  • Java系统中拆分同步和异步详解

    前言 很多开发人员说,将应用程序切换到异步处理很复杂.因为他们有一个天然需要同步通信的Web应用程序.在这篇文章中,我想介绍一种方法来达到异步通信的目的:使用一些众所周知的库和工具来设计他们的系统. 下面的例子是用Java编写的,但我相信它更多的是基本原理,同一个应用程序可以用任何语言来重新写. 所需的工具和库: Spring Boot RabbitMQ 1.Web应用程序 一个用Spring MVC编写的Web应用程序并运行在Tomcat上. 它所做的只是将一个字符串发送到一个队列中 (异步通

  • Java异步调用转同步的方法

    先来说一下对异步和同步的理解: 同步调用:调用方在调用过程中,持续等待返回结果. 异步调用:调用方在调用过程中,不直接等待返回结果,而是执行其他任务,结果返回形式通常为回调函数. 其实,两者的区别还是很明显的,这里也不再细说,我们主要来说一下Java如何将异步调用转为同步.换句话说,就是需要在异步调用过程中,持续阻塞至获得调用结果. 不卖关子,先列出五种方法,然后一一举例说明: 使用wait和notify方法 使用条件锁 Future 使用CountDownLatch 使用CyclicBarri

  • Spring的事件和监听器-同步与异步详解

    目录 Spring的事件和监听器-同步与异步 1.首先新建StartWorkflowEvent.java, 2.新建一个监听器StartWorkflowListener.java 3.创建一个事件发布类EventPublisher.java 4.相关的配置 Spring事件.异步监听 这可以对系统进行解耦 Spring的事件和监听器-同步与异步 Application下抽象子类ApplicationContextEvent的下面有4个已经实现好的事件 ContextClosedEvent(容器关

  • Awaitility同步异步工具实战示例详解

    目录 引言 1. awaitility入门 1.1 静态导入 1.2 简单例子 2. awaitility在RocketMQ中的实战 3. 总结 引言 在编写测试用例的时候遇到有异步或者队列处理的时候经常会用到 Thread.sleep() 等待来进行测试.例如:DLedger 测试选举的过程.当DLedger Leader下线.此时DLedger会重新发起选举,这个选举的过程是需要一定时间.很多时候在测试代码中就会使用 Thread.sleep . 由于选举需要的时间多少不确定所以sleep时

  • Vue3中Vuex状态管理学习实战示例详解

    目录 引言 一.目录结构 二.版本依赖 三.配置Vuex 四.使用Vuex 引言 Vuex 是 Vue 全家桶重要组成之一,专为 Vue.js 应用程序开发的 状态管理模式 + 库 ,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 一.目录结构 demo/ package.json vite.config.js index.html public/ src/ api/ assets/ common/ components/ store/ index.

  • Redhat持久化日志实战示例详解

    目录 持久化日志 实战练习:收集信息 持久化日志 默认情况下,Red Hat Enterprise Linux 7将系统日志存储在/run/log/journal中,该日志存储在tmpfs(临时文件系统)上.这意味着在重新启动时,所有存储的信息都将丢失.如果目录/var/log/journal存在,日志将存储在那里,从而在重新引导后启用持久日志. 可以通过使用以下步骤来启用持久性日志: mkdir/var/log/journal chown root:systemd-journal /var/l

  • Gin与Mysql实现简单Restful风格API实战示例详解

    目录 It works main.go 编译运行 数据库 CURD 增删改查 增 查 查询列表 Query 查询单条记录 QueryRow 改 删 组织代码 封装模型方法 Handler函数 组织项目 数据库处理 数据model封装 handler 路由 分组路由 app入口 总结 我们已经了解了Golang的Gin框架.对于Webservice服务,restful风格几乎一统天下.Gin也天然的支持restful.下面就使用gin写一个简单的服务,麻雀虽小,五脏俱全.我们先以一个单文件开始,然

  • Kotlin Coroutines执行异步加载示例详解

    前言 Kotlin Coroutines是Kotlin推出的新的异步API.并不是解决所有问题的最优方案,但是希望在许多情况下它会使事情变得更容易一些.这里只简单的展示一下这个库在安卓中的具体使用方案.下面话不多说了,来一起看看详细的介绍吧. 引入Coroutines //在application的build.gradle文件中的android节点添加如下的代码 kotlin { experimental { coroutines 'enable' } } //添加下面两行到依赖中 implem

  • Flutter 异步编程之单线程下异步模型图文示例详解

    目录 一. 本专栏图示概念规范 1. 任务概念规范 2. 任务的状态 3. 时刻与时间线 4.同步与异步 二.理解单线程中的异步任务 1. 任务的分配 2.异步任务特点 3. 异步任务完成与回调 三. Dart 语言中的异步 1.编程语言中与异步模型的对应关系 2.Dart 编程中的异步任务 3.当前任务分析 四.异步模型的延伸 1. 单线程异步模型的局限性 2. 多线程与异步的关系 3. Dart 中如何解决单线程异步模型的局限性 一. 本专栏图示概念规范 本专栏是对 异步编程 的系统探索,会

  • MySQL主从同步中的server-id示例详解

    前言 当我们搭建MySQL集群时,自然需要完成数据库的主从同步来保证数据一致性.而主从同步的方式也分很多种,一主多从.链式主从.多主多从,根据你的需要来进行设置.但只要你需要主从同步,就一定要注意server-id的配置,否则会出现主从复制异常. 在控制数据库数据复制和日志管理中,有两个重要的配置:server-id和server-uuid,他们会影响二进制日志文件记录和全局事务标识. server-id配置 当你使用主从拓扑时,一定要对所有MySQL实例都分别指定一个独特的互不相同的serve

  • Spring Boot之@Async异步线程池示例详解

    目录 前言 一. Spring异步线程池的接口类 :TaskExecutor 二.简单使用说明 三.定义通用线程池 1.定义线程池 2.异步方法使用线程池 3.通过xml配置定义线程池 四.异常处理 五.问题 前言 很多业务场景需要使用异步去完成,比如:发送短信通知.要完成异步操作一般有两种: 1.消息队列MQ 2.线程池处理. 我们来看看Spring框架中如何去使用线程池来完成异步操作,以及分析背后的原理. 一. Spring异步线程池的接口类 :TaskExecutor 在Spring4中,

  • Java手机号码工具类示例详解(判断运营商、获取归属地)

    所需引用Jar包 <dependency> <groupId>com.googlecode.libphonenumber</groupId> <artifactId>geocoder</artifactId> <version>2.15</version> </dependency> <dependency> <groupId>com.googlecode.libphonenumber&

  • Python网络爬虫中的同步与异步示例详解

    一.同步与异步 #同步编程(同一时间只能做一件事,做完了才能做下一件事情) <-a_url-><-b_url-><-c_url-> #异步编程 (可以近似的理解成同一时间有多个事情在做,但有先后) <-a_url-> <-b_url-> <-c_url-> <-d_url-> <-e_url-> <-f_url-> <-g_url-> <-h_url-> <--i_ur

随机推荐

其他