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

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

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

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

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

  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

异步过程的自动化测试相关推荐

  1. nodejs异步测试_异步过程的自动化测试

    nodejs异步测试 自从我开发了具有异步行为的服务器端应用程序以来已经有一段时间了,而该行为还不是事件驱动的系统. 异步行为始终是设计和测试中一个有趣的挑战. 通常,异步行为不应该很难进行单元测试– ...

  2. node.js 多个异步过程判断执行是否完成

    场景:想请求量较大的网络数据,比如想获取1000条结果,但数据处理速度慢,有超时的风险,可以分成10次处理,每次处理100条:所有请求完成后再统一进行处理. 这样的应用场景,可以这样处理: 方案一:判 ...

  3. 《Selenium自动化测试指南》—第1章1.1节自动化测试基础

    本节书摘来自异步社区<Selenium自动化测试指南>一书中的第1章1.1节自动化测试基础,作者赵卓,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.1 自动 ...

  4. 简单理解浏览器的event loop 和 JavaScript的同步异步

    为什么JavaScript是单线程的? JavaScript的主要用途是和用户进行交互以及对DOM的操作,为了避免复杂的同步问题(如果多线程,A线程对某DOM添加内容,B线程对它又进行了删除操作,这往 ...

  5. 并发、并行、串行、同步、异步、阻塞、非阻塞

    并发.并行.串行.同步.异步.阻塞.非阻塞 实际上同步与异步是针对应用程序与内核的交互而言的. 同步过程中进程触发IO操作并等待(也就是我们说的阻塞)或者轮询的去查看IO操作(也就是我们说的非阻塞)是 ...

  6. 今天清华学长手把手带你做UI自动化测试

    互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自 ...

  7. 清华学长手把手带你做UI自动化测试

    互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自 ...

  8. Javascript中的异步

    在C#,Java中,异步方法,通常是伴随多线程,并发等术语一起出现的,比如C#中的async方法,是运行在一个线程池线程上,并且在异步方法运行完成后,有一个回调函数通知主线程. 那么由于Javascr ...

  9. 如何从异步调用返回响应?

    我有一个函数foo ,它发出Ajax请求. 如何返回foo的响应? 我尝试从success回调中返回值,以及将响应分配给函数内部的局部变量并返回该局部变量,但这些方法均未真正返回响应. functio ...

最新文章

  1. mysql-master/slave同步问题:Slave_IO_Running: No
  2. altium designer 原理图和PCB 多通道设计
  3. LeetCode Regular Expression Matching(.和*通配符匹配)
  4. 在Activity不可见时暂停WebView的语音播放,可见时继续播放之前的语音
  5. 鸿蒙卡片-物联网DTU污水液位计卡片
  6. Linux memcache操作命令
  7. webpack4.x中使用postcss-loader、autoprefixer给CSS属性自动添加前缀
  8. 计算机tlv简介_TLV编码格式详解
  9. catia装配体怎么把零件旋转180度_各种装配夹具,来看看适合你用的
  10. 《网站建设与网页设计从入门到精通Dreamweaver+Flash+Photoshop+HTML+CSS+JavaScript》——3.3 添加文本元素...
  11. 新手如何从零开始学习unity
  12. WinHex V14.6 SR-2 注册码
  13. VS2010 正式版 破解方法详解 1
  14. 项目经理需要具备四种基本素质及八大管理技能
  15. Python学习笔记——python基础 2. 高级变量类型(列表、元祖、字典)
  16. Vmware虚拟机文件复制及改名称方法
  17. 驾驭你的“职场布朗运动” (作者李云)
  18. php opcode 启用,Drupal8安装提示PHP OPCODE CACHING未启用的解决方法
  19. SpringBoot配置全局异常捕获
  20. jsp中定义日期格式

热门文章

  1. artTemplate的空白输出坑
  2. 去BAT面试完的Mysql面试题总结(55道)
  3. 一篇文章搞定面试中的二叉树
  4. 你不知道ADo.Net中操作数据库的步骤【超详细整理】
  5. JAVA基础学习大全(笔记)
  6. 如何在Intellij IDEA中集成Gitlab
  7. python开发工具下所有软件都打不开_Python 开发工具链全解
  8. linux虚拟机tomcat上部署web项目的常用命令
  9. 魔术方法 类 序列化_Java序列化魔术方法及其示例使用
  10. netflix 模式创新_创新设计模式:工厂模式