併發(Concurrent) vs 並行(Parallel)
一談到並行測試,很多人自然而然的想到了使用多執行緒來執行測試的方式。其實多執行緒執行的方式叫做併發,並不能做到完全的並行,特別是針對目前大部分虛擬機器都是多核CPU,併發測試並不能完全發揮硬體的計算能力。讓我們先看看併發和並行的概念吧:
- 併發:多個任務在同一個 CPU 核上按細分的時間片輪流(交替)執行,從邏輯上來看那些任務是同時執行。針對 CPU 核心來說,任務仍然是按細粒度的序列執行。
- 並行:區別與序列,多個任務真正的分配到不同的 CPU 核心上去執行的,它們是真正的同時執行。
更通俗一點的類比,併發是多輛馬車在同一個賽道上跑;
並行是多賽道,馬車在各自的賽道上跑,彼此不受影響。
併發測試 vs 並行測試
類似的概念也應用到了Maven Surefire 執行所有測試用例的行為上,基於不同的配置:
- 測試併發執行 — 所有測試用例邏輯上在同一個 JVM 上執行,使用多執行緒分割測試執行集
- 測試並行執行 — 所有測試用例可進行分組跑在多個的 JVM 上,使用多程式分割測試測試集
測試程式碼要求 | 資源消耗 (CPU、記憶體) | 穩定性 | |
---|---|---|---|
併發測試 | 高,必須做到執行緒安全 | 少 | 差,存在資源競爭,很難重現問題 |
並行測試 | 低,無 | 多 | 好,資源隔離 |
針對各種測試場景,採用多執行緒和多程式方式執行測試優化的能力大致如下:
CPU密集型 | 檔案讀寫 | 網路請求 | |
---|---|---|---|
多執行緒 | 小,無法改善執行效率 | 中,效率改善提現在讀寫大檔案 | 大,網路延時往往超過時間片切換時間 |
多程式 | 大,能夠利用計算機的多核優勢 | 大,不管大小檔案都能夠改進效率 | 中,建立程式效率低 |
結論:CPU密集任務一般用多程式提高執行效率,網路請求任務一般用多執行緒提高執行效率,檔案讀寫看主要是CPU計算耗時還是等待耗時
執行策略
並行和併發測試不是互斥的,正好相反,可以根據的硬體測試環境來響應指定對應的策略。通過測試執行觀察平均的CPU和記憶體的利用率,在CPU有空閒利用率的情況先,優先新增程式,在CPU利用率滿負荷的情況,可以適當新增執行緒來進一步提升效率,一般的經驗是多執行緒數 = n*處理器核心數,過多的程式執行緒數不但不會提高效能,反而還會因為執行緒間的頻繁切換而受影響,具體需要根據執行緒處理的業務考略,不斷調整執行緒數個數,確定當前系統最優的執行緒數。
從實踐角度上說,maven的surefire的外掛可以同時支援forkCount (多程式)和parallel(多執行緒)
- parallel:可以指定是class還是suite,還是all,同時指定threadCount確定執行緒個數
- forkCount: 指定是多少個程式,同時通過reuseForks確定是否重用程式,還是每次新開
具體可以參考surefire的文件
排程優化
當應用了並行測試提高測試執行效率以後,跟木桶原理一樣,整個測試計劃的執行時間取決於最耗時的程式或者最耗時的執行緒,如果執行排程不合理,很有可能不能達到節省執行時間的目的。
推薦對每個case執行的時間做記錄,統計順序執行所有case的時間T,然後根據程式*執行緒的個數N,計算每個執行緒理論上平均時間T/N,把這個作為基準值,去拼裝case的執行序列,從而讓執行時間無限接近於T/N。