等待正确的时刻–集成测试

当您必须测试多线程程序时,总是需要等到系统达到特定状态后,测试才能验证是否达到了正确的状态。

这样做的通常方法是在系统中插入一个“探针”,该探针将向同步原语发出信号 (例如Semaphore ),并且测试将一直等到信号量得到信号或超时通过。 (您永远不应该做的两件事,但是经常犯错误,就是将睡眠插入代码中(因为它们会使您变慢并且变得脆弱),或者使用Object.wait方法而不进行循环处理(因为您可能会感到虚假)唤醒会导致虚假,难以诊断和非常令人沮丧的测试失败。

这一切都很好,也很不错(尽管有些冗长-至少要等到Java 8 lambda到达为止),但是如果第二个线程调用了第三个线程并且不等待它完成,该怎么办,但是在测试中我们要等待为了它? 一个具体的例子是:集成测试,它验证由客户端组成的,通过消息中间件与数据网格进行通信的系统是否将数据正确写入数据网格? 当然,我们将使用模拟中间件和模拟数据网格,因此启动/关闭和处理将非常快,但它们仍将是异步的(假设由于生产环境不是同步的而我们无法使其同步)编写代码以使其依赖于此事实)。

在下面的序列图中直观地描述了这种情况:我们在T0上运行了测试,我们希望它等待T3上的任务完成后再检查系统到达的状态。

我们可以通过对执行框架(可能是某种执行器)进行少量修改来实现此目的。 给定以下界面:

public interface ActivityCollector {void before();        void after();
}

我们将在任务排队等待执行时调用before() ,在执行任务after()调用after() (这些通常会在不同的线程上发生)。 如果现在我们考虑在增加计数器之前和之后减少计数器,我们可以等待计数器变为零(具有适当的同步),此时我们知道所有任务都已由系统处理。 您可以在此处找到执行此功能的执行程序。 在生产中,您当然可以使用不执行任何操作的接口实现,从而消除了任何性能开销。

现在让我们看一下定义我们如何等待“已处理”条件的接口:

interface ActivityWatcher {void await(long time, TimeUnit timeUnit);
}

这里使用的两个个人设计选择是:仅提供一种等待特定时间且不再等待的方法(如果测试花费的时间太长,则可能需要考虑性能下降),并使用未经检查的异常来编写测试代码较短。

最后一个功能是在任务执行期间收集异常,如果某处存在异常,则立即中止而不是超时。 这意味着我们将界面修改如下:

public interface ActivityCollector {void before();        void after();void collectException(Throwable t);
}

包装执行的代码如下所示:

try {command.run();
} catch (Throwable t) {activityCollector.collectException(t);throw t;
} finally {activityCollector.after();
}

您可以在此处找到ActivityWatcher / ActivityCollector的实现(它们之间是非常紧密的联系,因此一个类同时实现了两者)。 测试愉快!

注意事项:

  • 这需要对生产代码进行一些修改,因此它可能不是最佳的解决方案(例如,您可以尝试创建子系统的同步模拟并以这种方式进行测试)。
  • 该解决方案不适用于涉及计时器的情况,因为有时“没有任务在等待”,但实际上某个任务正在计时器中等待。 您可以通过使用自定义计时器来解决此问题,该计时器在计划任务时调用“ before”,在任务完成时调用“ after”。
  • 如果您使用网络通信以提高可靠性(即使它位于同一进程中),可能会出现相同的问题:有时会因为未在系统网络中序列化任务而没有安排任何任务。
  • ActivityCollector是单个同步点。 因此,这可能会降低性能,并可能隐藏并发错误。 有很多更复杂的方法可以实现它,从而避免了一些同步开销(例如使用ConcurrentLinkedQueue),但是您不能完全消除它。

PS。 该示例基于我似乎找不到的IBM文章(亲爱的lazyweb:如果有人找到它,请在其中打上“ tick / tock”之前/之后发表评论)以及我的同事的工作。 我唯一的角色是编写并合成它。

参考: 等待正确的时机–在 Java Advent Calendar博客上,我们的JCG合作伙伴 Attila-Mihaly Balazs进行了集成测试 。

翻译自: https://www.javacodegeeks.com/2012/12/waiting-for-the-right-moment-in-integration-testing.html

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

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

相关文章

网络编程---黏包

基于UDP协议的socket udp的server 不需要进行监听也不需要建立连接,在启动服务之后只能被动的等待客户端发送消息过来。 客户端发送消息的同时还会 自带地址信息,消息回复的时候 不仅需要发送消息 还需把对方的地址填上。 udp的client 不需要connect 因为…

CSS布局(二) 盒子模型属性

盒子模型的属性 宽高width/height 在CSS中,可以对任何块级元素设置显式高度。 如果指定高度大于显示内容所需高度,多余的高度会产生一个视觉效果,就好像有额外的内边距一样; 如果指定高度小于显示内容所需高度,取决于…

Extjs 下拉框

刚刚熟练了easyui控件的使用,又開始了如今的这个项目。这个项目是个半成品。前端使用的是Extjs控件,jsp中没有代码。就引用了非常多的js。。。于是乎有种不知所措了呀。。。 说实话特别的不想去看那些代码,第一是不熟悉,第二是太乱…

Java中的贷款模式(又名贷方承租人模式)

这篇文章是关于在Java中实现贷款模式的。 用例 在保存资源的代码与访问资源的代码之间实现分离,从而使访问代码无需管理资源。 当我们编写用于读取/写入文件或查询SQL / NOSQL数据库的代码时,上述用例适用。 在AOP的帮助下,肯定有API处理了此…

python亲密度_859. 亲密字符串(Python)

题目难度&#xff1a;★★☆☆☆类型&#xff1a;字符串给定两个由小写字母构成的字符串 A 和 B &#xff0c;只要我们可以通过交换 A 中的两个字母得到与 B 相等的结果&#xff0c;就返回true &#xff1b;否则返回 false 。提示0 < A.length < 200000 < B.length &l…

开发电子商城1

1 从阿里云的镜像 下载centos 6.8 64位 https://mirrors.aliyun.com/centos/6.8/isos/x86_64/CentOS-6.8-x86_64-bin-DVD1.iso 2&#xff1a;用vm安装 选定basic service版本 3&#xff1a;将Centos的yum源更换为国内的阿里云源 http://www.centoscn.com/image-text/config/20…

静态工厂方法与传统构造方法

之前&#xff0c;我已经讨论过一些关于Builder模式的信息 &#xff0c; Builder Pattern是一种有用的模式&#xff0c;用于实例化具有多个&#xff08;可能是可选的&#xff09;属性的类&#xff0c;这些属性可以使读取&#xff0c;编写和维护客户端代码更加容易&#xff0c;还…

python输入代码界面通常_vscode写python时的代码错误提醒和自动格式化的方法

python的代码错误检查通常用pep8、pylint和flake8&#xff0c;自动格式化代码通常用autopep8、yapf、black。这些工具均可以利用pip进行安装&#xff0c;这里介绍传统的利用pip.exe安装和在VScode中安装两种方式。【温馨提醒】要使用flake8或要想flake8等工具起作用&#xff0c…

HTML/CSS 知识点

本文是从简书复制的, markdown语法可能有些出入, 想看"正版"和更多内容请关注 简书: 小贤笔记 整个前端开发的工作流程 产品经理提出项目需求UI出设计稿前端人员负责开发静态页面(跟前端同步的后台人员在准备数据)前后台的交互测试产品上线(后期项目维护) 互联网原…

枚举枚举和修改“最终静态”字段的方法

在本新闻通讯中&#xff0c;该新闻通讯最初发表在Java专家的新闻通讯第161期中&#xff0c;我们研究了如何使用sun.reflect包中的反射类在Sun JDK中创建枚举实例。 显然&#xff0c;这仅适用于Sun的JDK。 如果需要在另一个JVM上执行此操作&#xff0c;则您可以自己完成。 这一…

java编译找不到符号_关于久违的Javac,编译出现“找不到符号”

参考文档&#xff1a;http://blog.csdn.net/qq369201191/article/details/49946609工作以来习惯了maven编译&#xff0c;已经忘记了javac这个东东&#xff0c;以至于遇到javac问题时困惑了&#xff0c;下面总结一下&#xff0c;以便后者参考。一、使用javac进行项目java文件编译…

CSS--居中方式总结

一、水平居中方法 1.行内元素、字体的水平居中 1.对于行内元素&#xff08;display值为inline或inline-block都可以&#xff09;或者字体&#xff1a;父元素添加css规则&#xff1a;text-align&#xff1a;center; <style> p{/*关键*/text-align:center; }ul{/*关键*/…

009-MailUtils工具类模板

版本一&#xff1a;JavaMail的一个工具类 package ${enclosing_package};import java.security.GeneralSecurityException; import java.util.Properties;import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.ma…

HTML5 Video标签

1.代码格式 <video width"320" height"240" controls><source src"movie.mp4" type"video/mp4"><source src"movie.ogg" type"video/ogg">您的浏览器不支持Video标签。</video>视频格式及…

某些小时后MySql连接自动掉线

MySql配置为删除任何闲置超过8小时的连接。 这意味着什么&#xff1f; 在8个小时的间隔后返回到已部署的应用程序之后&#xff08;如果未更改默认SQL参数&#xff09;&#xff0c;将会遇到异常情况。 如何解决这个问题&#xff1f; 增加wait_time参数-不是一个好主意&#xff…

AutoMapper的使用

本来是想洋洋洒洒写点儿关于这个神奇的具体使用方法&#xff0c;但是发现园子里已经有了&#xff0c;URL奉上&#xff1a;http://www.cnblogs.com/CreateMyself/p/7635429.html&#xff0c;直接打开撸就行。转载于:https://www.cnblogs.com/pangjianxin/p/8367589.html

shopxx 阿里云OSS设置

shopxx 使用文档没有啊&#xff0c;只能自己看了 数据中心 字段其实是 EndPoint字段 URL前缀 是 图片服务器的主机地址。这个在阿里云回传的时候是不带的。 对应 阿里OSS 外网域名 转载于:https://www.cnblogs.com/nanahome/p/7346641.html

bio java 例子_JAVA BIO 服务器与客户端实现示例

代码只兼容JAVA 7及以上版本。服务器端代码&#xff1a;package com.stevex.app.bio;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import j…

我的HTML总结之常用基础便签

HTML&#xff1a;是Hyper Text Markup Language&#xff08;超级文本标记语言&#xff09;的缩写&#xff0c;HTML不是一种程序&#xff0c;只是一种控制网页中数据显示的标识语言。 HTML由一组标签组成。 HTML的基本结构 <html> <head> <title>第一个HTML示…

您是否应该信任JVM中的默认设置?

如今&#xff0c;JVM被认为是智能的。 预期不会进行太多配置–只需设置要在启动脚本中使用的最大堆&#xff0c;您就可以进行了。 所有其他默认设置都很好。 大概我们当中有些人误以为。 实际上&#xff0c;在运行时期间发生了很多事情&#xff0c;无法自动调整性能&#xff0c…