Awaitility同步異步工具實戰示例詳解
引言
在編寫測試用例的時候遇到有異步或者隊列處理的時候經常會用到 Thread.sleep() 等待來進行測試。例如:DLedger 測試選舉的過程。當DLedger Leader下線。此時DLedger會重新發起選舉,這個選舉的過程是需要一定時間。很多時候在測試代碼中就會使用 Thread.sleep 。
由於選舉需要的時間多少不確定所以sleep時間就會設置為開發者經驗的最大值。這樣會造成測試代碼會變得很慢。 當然開發者可以通過自己輪詢來實現減少時間的消耗。
下面介紹一個處理這個一類問題的工具:awaitility
1. awaitility入門
Maven:
<dependency> <groupId>org.awaitility</groupId> <artifactId>awaitility</artifactId> <version>xxxx</version> <scope>test</scope> </dependency>
文章編寫的時候版本為:4.2.0
1.1 靜態導入
為瞭有效地使用Awaitility,建議從Awaitility框架中靜態地導入以下方法:
org.awaitility.Awaitility.*
在使用的時候需要搭配Java的時間相關的類以及Junit相關類:
java.time.Duration.*
java.util.concurrent.TimeUnit.*
org.junit.Assert.*
1.2 簡單例子
例子1:
await().until(newUserIsAdded());
等待直到執行newUserIsAdded()返回true. 這個是沒有返回值的。
例子2:
await().atMost(5, SECONDS).until(newUserWasAdded());
最多等待5秒,等待直到執行newUserIsAdded()返回true. 這個是沒有返回值的。
例子3:
await().until( userRepositorySize(), equalTo(1) );
等待直到執行userRepositorySize()返回方法對應的值. 這個是有返回值
更多的例子可以參照官網 使用例子
2. awaitility在RocketMQ中的實戰
在RocketMQ的test cases 中有一些使用瞭 Thread.sleep,接下來我們看看如何使用awaitility進行優化,減少測試用例的執行時間。以ControllerManagerTest測試用例為例子來解決,在代碼中可以看到有這樣的代碼:
上圖框出來的代碼主要的作用是什麼呢?等待Broker的Master過期,但是過期的時間我們根據設置的心跳的過期時間來預估時間。所以這裡填寫的是6秒當然你也可以填寫10秒或者更長。
解決之前的執行時間:
使用awaitility對代碼進行改造重構:
重構後的代碼,如上圖的紅線框出來部分。當然我這裡還對其他的進行處理。
有興趣的可以關註一下RocketMQ的這個ISSUE:github.com/apache/rock…
使用awaitility重構後的執行時間:
時間有明顯的下降。相比之前的下降瞭5秒左右。
3. 總結
- 在測試過程中引入awaitility能夠很大程度上方便測試,無需要每次都憑經驗去預估時間。並且很多時候這個Thread.sleep的時間不是很好估算。減少瞭單元測試執行的時間。特別是像RocketMQ這樣大型的項目單元測試很多。並且很多都是去測試分佈式的,如果使用Thread.sleep會導致整個單元測試的時間很長。
- 無需自己去實現輪詢來減少單元測試的時間。
以上就是Awaitility同步異步工具實戰示例詳解的詳細內容,更多關於Awaitility同步異步工具實的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- springBoot Junit測試用例出現@Autowired不生效的解決
- 基於SpringBoot Mock單元測試詳解
- Java單元測試工具之JUnit的使用
- SpringBoot與單元測試JUnit的結合操作
- Maven依賴中scope的含義