等待正确的时刻–集成测试
當您必須測試多線程程序時,總是需要等到系統達到特定狀態后,測試才能驗證是否達到了正確的狀態。
這樣做的通常方法是在系統中插入一個“探針”,該探針將向同步原語發出信號 (例如Semaphore ),并且測試將一直等到信號量得到信號或超時通過。 (您永遠不應該做的兩件事,但是經常犯錯誤,就是將睡眠插入代碼中(因為它們會使您變慢并且變得脆弱),或者使用Object.wait方法而不進行循環處理(因為您可能會感到虛假)喚醒會導致虛假,難以診斷和非常令人沮喪的測試失敗。
這一切都很好,也很不錯(盡管有些冗長-至少要等到Java 8 lambda到達為止),但是如果第二個線程調用了第三個線程并且不等待它完成,該怎么辦,但是在測試中我們要等待為了它? 一個具體的例子是:集成測試,它驗證由客戶端組成的,通過消息中間件與數據網格進行通信的系統是否將數據正確寫入數據網格? 當然,我們將使用模擬中間件和模擬數據網格,因此啟動/關閉和處理將非常快,但它們仍將是異步的(假設由于生產環境不是同步的而我們無法使其同步)編寫代碼以使其依賴于此事實)。
在下面的序列圖中直觀地描述了這種情況:我們在T0上運行了測試,我們希望它等待T3上的任務完成后再檢查系統到達的狀態。
我們可以通過對執行框架(可能是某種執行器)進行少量修改來實現此目的。 給定以下界面:
public interface ActivityCollector {void before(); void after(); }我們將在任務排隊等待執行時調用before() ,在執行任務after()調用after() (這些通常會在不同的線程上發生)。 如果現在我們考慮在增加計數器之前和之后減少計數器,我們可以等待計數器變為零(具有適當的同步),此時我們知道所有任務都已由系統處理。 您可以在此處找到執行此功能的執行程序。 在生產中,您當然可以使用不執行任何操作的接口實現,從而消除了任何性能開銷。
現在讓我們看一下定義我們如何等待“已處理”條件的接口:
interface ActivityWatcher {void await(long time, TimeUnit timeUnit); }這里使用的兩個個人設計選擇是:僅提供一種等待特定時間且不再等待的方法(如果測試花費的時間太長,則可能需要考慮性能下降),并使用未經檢查的異常來編寫測試代碼較短。
最后一個功能是在任務執行期間收集異常,如果某處存在異常,則立即中止而不是超時。 這意味著我們將界面修改如下:
public interface ActivityCollector {void before(); void after();void collectException(Throwable t); }包裝執行的代碼如下所示:
try {command.run(); } catch (Throwable t) {activityCollector.collectException(t);throw t; } finally {activityCollector.after(); }您可以在此處找到ActivityWatcher / ActivityCollector的實現(它們之間是非常緊密的聯系,因此一個類同時實現了兩者)。 測試愉快!
注意事項:
- 這需要對生產代碼進行一些修改,因此它可能不是最佳的解決方案(例如,您可以嘗試創建子系統的同步模擬并以這種方式進行測試)。
- 該解決方案不適用于涉及計時器的情況,因為有時“沒有任務在等待”,但實際上某個任務正在計時器中等待。 您可以通過使用自定義計時器來解決此問題,該計時器在計劃任務時調用“ before”,在任務完成時調用“ after”。
- 如果您使用網絡通信以提高可靠性(即使它位于同一進程中),可能會出現相同的問題:有時會因為未在系統網絡中序列化任務而沒有安排任何任務。
- ActivityCollector是單個同步點。 因此,這可能會降低性能,并可能隱藏并發錯誤。 有很多更復雜的方法可以實現它,從而避免了一些同步開銷(例如使用ConcurrentLinkedQueue),但是您不能完全消除它。
PS。 該示例基于我似乎找不到的IBM文章(親愛的lazyweb:如果有人找到它,請在其中打上“ tick / tock”之前/之后發表評論)以及我的同事的工作。 我唯一的角色是編寫并合成它。
參考: 等待正確的時機–在 Java Advent Calendar博客上,我們的JCG合作伙伴 Attila-Mihaly Balazs進行了集成測試 。
翻譯自: https://www.javacodegeeks.com/2012/12/waiting-for-the-right-moment-in-integration-testing.html
總結
以上是生活随笔為你收集整理的等待正确的时刻–集成测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑屏幕颜色怎么改如何更换电脑屏保
- 下一篇: 静态工厂方法与传统构造方法