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