异步过程的自动化测试

自从我开发了具有异步行为的服务器端应用程序以来已经有一段时间了,该行为还不是事件驱动的系统。 异步行为始终是设计和测试中一个有趣的挑战。 通常,异步行为不应该很难进行单元测试-毕竟,动作的行为不一定必须在时间上进行耦合(请参见耦合形式 )。

提示:如果在单元测试中发现需要异步测试,则可能是做错了,需要重新设计代码以消除这些顾虑。

如果您的测试策略仅包括单元测试,您将错过一整套行为,而这些行为通常会在集成,功能或系统测试等高级测试中被发现,而这正是我需要异步测试的地方。

从概念上讲,异步测试实际上非常容易。 像同步测试一样,您需要采取措施,然后寻找所需的结果。 但是,与同步测试不同,测试不能保证在检查副作用或结果之前动作已经完成。

通常有两种方法来测试异步行为:

  1. 删除异步行为
  2. 轮询直到您具有所需的状态

删除异步行为

多年前,当TDD对胖客户端应用程序进行TDD时,我仍然使用这种方法,而在swing应用程序中编写应用程序仍然是一种常见的方法。 这样做需要将调用行为的行为隔离在一个地方,而不是在不同的线程中发生,而是在测试过程中发生在与测试相同的线程中。 我什至在2006年对此进行了介绍,并撰写了这份备忘单,介绍了该过程。

这种方法需要一种纪律性的设计方法,在这种情况下,将这种行为切换到一个单独的位置即可。

轮询直到您具有所需的状态

轮询是解决此问题的更为常见的方法,但是这涉及到等待和超时的常见问题。 等待时间过长会增加您的总体测试时间,并会延长反馈循环。 根据您的操作,等待时间太短可能也很昂贵(例如,不必要地锤击某些积分点)。

超时是异步行为的另一种诅咒,因为您实际上不知道何时要执行某项操作,但您实际上并不希望测试永远进行下去。

上一次我不得不做某事时,我们通常会最终编写自己的轮询和超时挂钩,而相对简单的现在可以作为非常简单的库使用。 幸运的是,其他人也在java-land遇到了这个问题,并提供了一个库来帮助简化Awaitility形式的测试 。

这是一个简单的测试,演示了该库使测试异步行为的容易程度:

package com.thekua.spikes.aysnc.testing;import com.thekua.spikes.aysnc.testing.FileGenerator;
import org.junit.Before;
import org.junit.Test;import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import static java.util.concurrent.TimeUnit.SECONDS;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;public class FileGeneratorTest {private static final String RESULT_FILE = "target/test/resultFile.txt";private static final String STEP_1_LOG = "target/test/step1.log";private static final String STEP_2_LOG = "target/test/step2.log";private static final String STEP_3_LOG = "target/test/step3.log";private static final List<String> FILES_TO_CLEAN_UP = Arrays.asList(STEP_1_LOG, STEP_2_LOG, STEP_3_LOG, RESULT_FILE);@Beforepublic void setUp() {for (String fileToCleanUp : FILES_TO_CLEAN_UP) {File file = new File(fileToCleanUp);if (file.exists()) {file.delete();}}}@Testpublic void shouldWaitForAFileToBeCreated() throws Exception {// Given I have an aysnc process to runString expectedFile = RESULT_FILE;List<FileGenerator> fileGenerators = Arrays.asList(new FileGenerator(STEP_1_LOG, 1, "Step 1 is complete"),new FileGenerator(STEP_2_LOG, 3, "Step 2 is complete"),new FileGenerator(STEP_3_LOG, 4, "Step 3 is complete"),new FileGenerator(expectedFile, 7, "Process is now complete"));// when it is busy doing its workExecutorService executorService = Executors.newFixedThreadPool(10);for (final FileGenerator fileGenerator : fileGenerators) {executorService.execute(new Runnable() {public void run() {fileGenerator.generate();}});}// then I get some log outputsawait().atMost(2, SECONDS).until(testFileFound(STEP_1_LOG));await().until(testFileFound(STEP_2_LOG));await().until(testFileFound(STEP_3_LOG));// and I should have my final result with the output I expectawait().atMost(10, SECONDS).until(testFileFound(expectedFile));String fileContents = readFile(expectedFile);assertThat(fileContents, startsWith("Process"));// CleanupexecutorService.shutdown();}private String readFile(String expectedFile) throws IOException {return new String(Files.readAllBytes(Paths.get(expectedFile)));}private Callable<Boolean> testFileFound(final String file) {return new Callable<Boolean>() {public Boolean call() throws Exception {return new File(file).exists();}};}
}

您可以在此公共git存储库上浏览完整的演示代码。

翻译自: https://www.javacodegeeks.com/2017/04/automated-tests-asynchronous-processes.html

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

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

相关文章

iphone以旧换新活动_iPhone第3轮降价背后:销售下滑库克甩锅给中国,国产手机崛起分食蛋糕...

排版 | 王科编辑 | 梁夜作者 | 吴晓宇来源 | 财经天下周刊(ID&#xff1a;cjtxzk)曾经吃掉手机行业9成利润的巨无霸公司苹果&#xff0c;不得不“自降身价”。3月5日之后&#xff0c;苏宁易购、京东、拼多多等多家电商平台纷纷宣布&#xff0c;再次对旗舰级iPhone XS系列产品降…

tf.placeholder()

# x 是手写图像的像素值,y是图像对应的标签 x tf.placeholder(tf.float32, [None,784])y tf.placeholder(tf.float32, [None,10])

Docker 搭建pxc集群 + haproxy + keepalived 高可用(二)

上一节我们有了两个分片的pxc集群&#xff0c;这一节我们接着安装haproxy和keepalived的实现集群的高可用 一、先下载haproxy的镜像 [rootlocalhost ~]# docker pull haproxy二、在host主机上写好配置文件&#xff0c;启动容器时候读取haproxy.cfg&#xff0c;vim /usr/local/d…

.net httpwebrequest 并发慢_go语言并发之MPG模型

请记住go并发的真理&#xff1a;Do not communicate by sharing memory; instead, share memory by communicating.不要以共享内存的方式来通信&#xff0c;相反&#xff0c;要通过通信来共享内存。go语言天生的并发大家都知道&#xff0c;可是go是如何实现轻松的构造上万的协程…

python中os操作文件及文件路径

python中os操作文件及文件路径实例汇总 1 . python获取文件上一级目录&#xff1a;取文件所在目录的上一级目录 os.path.abspath(os.path.join(os.path.dirname(settings.py),os.path.pardir)) 2. os.path.pardir是父目录&#xff0c;os.path.abspath是绝对路径 printos.path.…

JVM内存管理(一)--GC简介

GC策略解决了哪些问题&#xff1f; 既然是要进行自动GC&#xff0c;那必然会有相应的策略&#xff0c;而这些策略解决了哪些问题呢&#xff0c;粗略的来说&#xff0c;主要有以下几点。 1、哪些对象可以被回收。 2、何时回收这些对象。 3、采用什么样的方式回收。 GC策略采用何…

java 自定义注释_带有自定义注释的Java注释教程

java 自定义注释Java批注提供有关代码的信息&#xff0c;并且它们对其批注的代码没有直接影响。 在本教程中&#xff0c;我们将学习Java注释&#xff0c;如何编写自定义注释 &#xff0c;注释用法以及如何使用反射来解析注释 。 注释是在Java 1.5中引入的&#xff0c;现在它已…

vue标准时间改为时间戳_正确的济南初中寒假放假时间安排出来啦!家长速戳→...

原标题&#xff1a;正确的济南初中寒假放假时间安排出来啦&#xff01;家长速戳→今年济南初中寒假放假时间↓↓↓ 2021年1月30日-2月26日第一学期1 寒假安排义务教育阶段学校寒假开始时间为2021年1月30日(腊月十八)&#xff0c;寒假结束时间为2月26日(正月十五)。高中阶段学校…

给深度学习入门者的Python快速教程 - 基础篇

Python快速教程 - 基础篇 5.1 Python简介 本章将介绍Python的最基本语法&#xff0c;以及一些和深度学习还有计算机视觉最相关的基本使用。 5.1.1 Python简史 Python是一门解释型的高级编程语言&#xff0c;特点是简单明确。Python作者是荷兰人Guido van Rossum&#xff0c…

模糊理论在机器人传感器中的应用_智能家电中的传感器应用大全

面对智能化家庭网络的逐渐普及和发展&#xff0c;各种各样的传感器引入到家电中变得更加迫切。人们希望家电能增加使用的舒适度、减少耗能和耗水、清洗方便、降低噪声和振动、提高使用质量、实现复杂的智能。以前传感器主要应用于温度控制和水平控制系统&#xff0c; 现在它们的…

用Java解析:您可以使用的所有工具和库

如果需要从Java解析语言或文档&#xff0c;则从根本上讲有三种方法可以解决问题&#xff1a; 使用支持该特定语言的现有库&#xff1a;例如用于解析XML的库 手动构建自己的自定义解析器 生成解析器的工具或库&#xff1a;例如ANTLR&#xff0c;可用于构建任何语言的解析器 …

一台服务器装两个sql server 如何访问吗_服务器多网卡多路由策略

场景背景与需求某公司新买一台服务器, 服务器资源(cpu,内存,硬盘)比较多,并且有多个网卡。运维工程师为了节省资源&#xff0c;在服务器上搭建多个服务&#xff0c;希望通过多个网卡实现流量分流。但由于运维工程师对网络理解不够深入&#xff0c;将服务器的多个网卡都配置了同…

python seed()

Python seed() 函数 seed() 方法改变随机数生成器的种子&#xff0c;可以在调用其他随机模块函数之前调用此函数。 以下是 seed() 方法的语法: import random random.seed ( [x] )注意&#xff1a;seed(()是不能直接访问的&#xff0c;需要导入 …

vue 路由知识点梳理及应用场景整理

最近做项目才发现&#xff0c;我确实对 vue-router 太不熟悉了&#xff0c;都只了解个简单用法就开始搞了&#xff0c;本来很简单的问题&#xff0c;都搞不清楚。现在重新看一遍文档&#xff0c;重新梳理一下。 vue 路由的原理 说实话&#xff0c;路由我一直也就光顾着用&#…

dct变换的主要优点有哪些_发泡保温材料包括哪些成分?主要优点是什么?有没有发展前景?...

在各个行业中&#xff0c;对发泡保温材料都有需求。随着这种材料越来越受欢迎&#xff0c;更多人开始关注它的成分与优点。了解的越多&#xff0c;越容易在合适的场合令其发挥功效。组成成分有哪些&#xff1f;对于发泡保温材料来说&#xff0c;包括甲组和乙组两部分。所谓的甲…

企业集成模式_企业集成模式简介

企业集成模式在此博客文章中&#xff0c;我们将介绍一些企业集成模式。 这些是旨在解决集成挑战的已知设计模式。 阅读此书后&#xff0c;您将可以设计集成解决方案。 EIP&#xff08;简而言之&#xff09;是已知的设计模式&#xff0c;可为应用程序集成过程中面临的问题/问题…

win7安装

以Dell电脑为例&#xff0c;其他品牌电脑类似 Dell安装win7 一&#xff1a;快捷启动U盘或光盘的方法&#xff1a; 1&#xff0c; 打开戴尔Dell电脑&#xff0c;当进入到标志画面时&#xff0c;马上按键盘上方的F12键&#xff0c;就能进入到快捷启动菜单。 2&#xff0c; 进…

【Bootstrap】 框架 栅格布局系统设计原理

前提条件&#xff08;Bootstrap 自带&#xff09; 首先使用这个布局之前要定义一下代码&#xff1a; 这行代码如果不懂&#xff0c;可以搜索一下&#xff0c;总之大致意思就是&#xff0c;被定义的元素的内边距和边框不再会增加它的宽度&#xff0c;不加入的话排版会有问题。 不…

asp.net接受表单验证格式后再提交数据_药物临床试验数据管理与统计分析的计划和报告指导原则...

来源&#xff1a;国家药监局网站一、前言规范的数据管理计划有助于获得真实、准确、完整和可靠的高质量数据&#xff1b;而详细的统计分析计划则有助于保证统计分析结论正确和令人信服。为保证临床试验数据的质量和科学评价药物的有效性与安全性&#xff0c;必须事先对数据管理…

使用Spring Boot应用程序将代码管道化

这是有关基于本地Docker compose堆栈的持续交付的一系列帖子中的最后一篇&#xff08;请参阅此处的第一篇和第二篇文章 &#xff09;。 在这篇文章中&#xff0c;我使用一个简单的Spring Boot项目来展示如何利用“ 管道作为代码 ”的概念。 请注意&#xff0c;这仅是示例&#…