异步过程的自动化测试
自從我開發(fā)了具有異步行為的服務(wù)器端應(yīng)用程序以來已經(jīng)有一段時(shí)間了,該行為還不是事件驅(qū)動(dòng)的系統(tǒng)。 異步行為始終是設(shè)計(jì)和測(cè)試中一個(gè)有趣的挑戰(zhàn)。 通常,異步行為不應(yīng)該很難進(jìn)行單元測(cè)試-畢竟,動(dòng)作的行為不一定必須在時(shí)間上進(jìn)行耦合(請(qǐng)參見耦合形式 )。
提示:如果在單元測(cè)試中發(fā)現(xiàn)需要異步測(cè)試,則可能是做錯(cuò)了,需要重新設(shè)計(jì)代碼以消除這些顧慮。
如果您的測(cè)試策略僅包括單元測(cè)試,您將錯(cuò)過一整套行為,而這些行為通常會(huì)在集成,功能或系統(tǒng)測(cè)試等高級(jí)測(cè)試中被發(fā)現(xiàn),而這正是我需要異步測(cè)試的地方。
從概念上講,異步測(cè)試實(shí)際上非常容易。 像同步測(cè)試一樣,您需要采取措施,然后尋找所需的結(jié)果。 但是,與同步測(cè)試不同,測(cè)試不能保證在檢查副作用或結(jié)果之前動(dòng)作已經(jīng)完成。
通常有兩種方法來測(cè)試異步行為:
刪除異步行為
多年前,當(dāng)TDD對(duì)胖客戶端應(yīng)用程序進(jìn)行TDD時(shí),我仍然使用這種方法,而在swing應(yīng)用程序中編寫應(yīng)用程序仍然是一種常見的方法。 這樣做需要將調(diào)用行為的行為隔離在一個(gè)地方,而不是在不同的線程中發(fā)生,而是在測(cè)試過程中發(fā)生在與測(cè)試相同的線程中。 我什至在2006年對(duì)此進(jìn)行了介紹,并撰寫了這份備忘單,介紹了該過程。
這種方法需要一種紀(jì)律性的設(shè)計(jì)方法,在這種情況下,將這種行為切換到一個(gè)單獨(dú)的位置即可。
輪詢直到您具有所需的狀態(tài)
輪詢是解決此問題的更為常見的方法,但是這涉及到等待和超時(shí)的常見問題。 等待時(shí)間過長(zhǎng)會(huì)增加您的總體測(cè)試時(shí)間,并會(huì)延長(zhǎng)反饋循環(huán)。 根據(jù)您的操作,等待時(shí)間太短可能也很昂貴(例如,不必要地錘擊某些積分點(diǎn))。
超時(shí)是異步行為的另一種詛咒,因?yàn)槟鷮?shí)際上不知道何時(shí)要執(zhí)行某項(xiàng)操作,但您實(shí)際上并不希望測(cè)試永遠(yuǎn)進(jìn)行下去。
上一次我不得不做某事時(shí),我們通常會(huì)最終編寫自己的輪詢和超時(shí)掛鉤,而相對(duì)簡(jiǎn)單的現(xiàn)在可以作為非常簡(jiǎn)單的庫(kù)使用。 幸運(yùn)的是,其他人也在java-land遇到了這個(gè)問題,并提供了一個(gè)庫(kù)來幫助簡(jiǎn)化Awaitility形式的測(cè)試 。
這是一個(gè)簡(jiǎn)單的測(cè)試,演示了該庫(kù)使測(cè)試異步行為的容易程度:
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存儲(chǔ)庫(kù)上瀏覽完整的演示代碼。
翻譯自: https://www.javacodegeeks.com/2017/04/automated-tests-asynchronous-processes.html
總結(jié)
以上是生活随笔為你收集整理的异步过程的自动化测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 唤怎么读 唤的意思
- 下一篇: 企业集成模式_企业集成模式简介