Docker引領測試革新
隨著Docker技術被越來越多的人所認可,其應用的范圍也越來越廣泛。本文將從測試類型、Devops、自動化測試、測試場景、測試實踐等方面介紹Docker對軟件測試技術的影響。我假設讀者在看這篇文章時已經對Docker和其所依賴的核心技術有了一定的了解。如
1.傳統軟件開發流程的痛點
在傳統軟件開發流程中,開發團隊在完成功能代碼編寫后,會首先進行自測,之后將代碼提交到Git倉庫中。在每一次迭代轉測試時,開發團隊會首先構建轉測試的二進制文件,之后由測試團隊對版本進行驗證,驗證通過后會將版本提交給運維團隊。之后再由運維團隊將產品發布件部署到運維服務器中以提供給客戶使用。
在這個流程中會有如下痛點:
(1)開發、測試和運維環境不統一。
這導致了有些本該在開發階段發現的軟件缺陷可能會遺漏到測試或運維階段才能發現。有時發布件在開發環境中運行的很穩定,而在運維環境中剛剛運行就掛掉了。這時運維團隊不得不找開發團隊來救火,導致了整個團隊工作效率下降。
(2)無法準確獲取客戶的軟件環境。
我們往往不能直接復現客戶報的軟件缺陷,不得不去客戶現場進行調試,滯后了解決問題的時間。
(3)開發者在提交代碼前往往未做充分的測試。
開發自驗工作取決于開發者的責任心,而沒有一種機制來保證自驗工作的進行。導致了很多低級的軟件缺陷遺漏到測試和運維團隊。
(4)開發團隊無法復現測試團隊報出的軟件缺陷,導致兩個團隊出現相互推諉的現象。
(5)配置測試環境的時間較長,測試自動化成本高。
傳統環境往往使用虛擬機,而其消耗資源高、部署速度慢,導致自動化的效率不高。
2.當前測試技術面臨的挑戰
主要的挑戰如下所示:
(1)配置一致的測試環境。
(2)快速部署軟件。
(3)并行執行測試,在并行的同時還需確保測試任務各自的環境不被污染。
(4)成功的復現軟件缺陷。
(5)創建清潔的測試環境。
(6)正確配置測試工具。同一個工具需要適配到不同的linux發行版中。
(7)快速部署多個測試主機。
(8)快速導入測試數據。
(9)快速清理測試環境。
(10)快速保留、復制、恢復測試環境。
3.Docker對測試技術的革命性影響
(1)更早的發現單元測試中的軟件缺陷。
測試驅動開發是軟件工程中一個具有里程碑意義的創新,即開發者在提交開發代碼的同時也要提供對應的測試代碼,在代碼提交后系統會自動進行一輪自動化測試。通過Docker可以快速部署測試環境,可以有力的支撐自動化測試,從而確保在第一時間發現單元測試中的軟件缺陷。
(2)為功能測試和集成測試提供清潔的測試環境。
很多公司由于成本問題,不得不在一個虛擬機中運行不同類型的測試任務。而這些任務在運行時往往會導致環境污染。通過Docker技術的隔離性,可以有效地解決測試環境的污染問題。
(3)讓測試團隊和客戶丟掉冗長的配置文檔。
開發轉測試時往往帶有較長的環境部署文檔,而在這些文檔中往往存在部署過程跳步的問題,測試團隊很難一次準確的將環境部署成功。而現在可以通過Docker鏡像將配置環境的過程簡化,測試團隊省去了查閱文檔的過程,只需要基于開發團隊提供的Docker鏡像就可以輕松的配置測試環境。
(4)便于復現客戶報告的軟件缺陷。
當客戶使用軟件發現缺陷時,可以將其所使用的環境打包成鏡像提供給開發團隊。開發團隊通過鏡像即可獲取與客戶一致的軟件環境。
(5)通過Dockerfile可以梳理好測試鏡像制作的流程。
如果流程步驟需要微調時(如將安裝gcc3.4改為安裝gcc4.3),可以將Dockerfile中對應的信息進行修改并重新創建新的鏡像,不必手動重新配置運行環境。
(6)可以將成熟的測試套或測試工具通過鏡像共享。
這樣可以支持軟件在不同linux發行版中成功的運行,軟件提供商可以將主要精力放在完善功能上,不必投入過多時間將軟件適配到不同的linux發行版中。
(7)利用Docker生態中的工具可以快速創建可伸縮的測試環境,大大減少了測試所消耗的時間。
可以在短時間內快速集中資源來完成一項測試任務,在任務完成后又可以快速的對資源 進行回收,有利于提升資源使用效率。
(8)優越的性能指標。
通過優于虛擬機的性能,Docker可以提升測試效率。通過“-v”選項可以將主機的目錄快速映射到容器中,可以實現測試文件的快速共享。通過“--rm”選項可以在測試完成后第一時間刪除容器,以便釋放系統資源。
(9)輕松的恢復測試環境(包括內存)-CRIU技術 Checkpoint Restore In Userspace
結合CRIU技術,可以實現容器運行狀態的保存,這項技術也是容器熱遷移的基礎。
4.DevOps與Docker
DevOps一詞的來自于Development和Operations的組合,突出重視軟件開發人員和運維人員的溝通合作,通過自動化流程來使得軟件構建、測試、發布更加快捷、頻繁和可靠。
在DevOps出現之前,軟件經過開發、測試后由運維團隊將發布件部署到公司的基礎設施上,并將服務提供給客戶使用。然而,開發、測試、運維三個團隊缺少有效協同工作的機制,導致部門墻嚴重。開發團隊往往關注新功能開發和快速迭代,而運維團隊關注的是發布件的穩定性,他們不希望版本頻繁的更替。往往在這兩個團隊間會爆發激烈的斗爭。
在DevOps出現之后,團隊通過協作和自動化的方式打通了開發、測試、運維團隊之間的壁壘。當有新的代碼提交時,系統在第一時間會觸發自動化測試,依次在開發自驗環境、測試環境、運維環境中驗證軟件,確保可以第一時間發現軟件缺陷。然而,當出現業務峰值時,傳統的基礎設施中的虛擬機就無法有效的應對了。
在后Devops時代,隨著云計算的普及,很多云平臺提供了應用引擎,如果你的應用符合引擎的規范,云平臺就可以自動檢測業務負載量。當業務出現峰值時,平臺可以利用底層容器技術的快速部署、資源快速擴展伸縮等特性來應對,從而有效的支撐了業務的正常運行。
5.Docker與自動化測試
對于重復枯燥的手動測試任務,可以考慮將其進行自動化改造。自動化的成本在于自動化程序的編寫和維護,而收益在于節省了手動執行用例的時間。簡而言之,如果收益大于成本,測試任務就有價值自動化,否則受益的只是測試人員的自動化技能得到了提升。利用Docker的快速部署、環境共享等特性,可以大大減少自動化的成本,使很多原本沒有價值自動化的測試任務變為了有價值自動化的任務,大大提升了項目效率。
那么如果自動化測試已經運行在了虛擬機中,是否有必要使用Docker技術將其進行改造?這個就要具體問題具體分析了。筆者并不贊同將所有測試任務一刀切的進行容器化改造。如果當前虛擬機已經滿足測試需求,你就需要評估一下引入Docker進行改造所需的成本,其中包含學習Docker技術所需要的時間成本。反之,如果虛擬機無法滿足當前的測試需求,可以考慮盡快引入Docker進行改造。
6.Docker的約束
Build, Ship, and Run Any App, Anywhere.這是Docker公司高調宣稱的口號,即在任何平臺都可以構建、部署、運行任何應用。然而,由于Docker自身的特點,其使用場景有一些約束:
(1)因為容器與主機共享內核,如果容器中應用需要不同的內核版本,就不得不更換主機內核。但如果主機內核變更后又會影響到其它容器的運行。變通的方法是將應用源碼的編寫與內核特性解耦。
(2)Docker使用時需要3.10或以上版本的內核,這是最低的限制。如果你需要使用更高級的Docker特性,如user namespace,那么還需要更高版本的內核。
(3)使用“--privileged”選項后可以在容器內加載或卸載內核模塊,但這個操作會影響到主機和其它容器。
(4)無法模擬不同平臺的運行環境,例如不能在x86系統中啟動arm64的容器。
(5)因為Docker采用了namespace的方案來實現隔離,而這種隔離屬于軟件隔離,安全性不高。不適合安全性高的測試任務。
(6)因為目前沒有time namespace技術,修改某個容器時間時就不得不影響到主機和其它容器。
7.適用于Docker的測試場景
由于容器與主機共享內核使用,凡是和內核無強相關的測試任務是適合引入Docker進行改造的,例如源碼編譯測試、軟件安裝測試、互聯網應用測試、數據庫測試等。而與內核強相關的測試任務是不適合使用Docker進行改造的,如內核網絡模塊測試、內核namespace特性測試等。
8.Docker測試實踐
8.1.容器化編譯系統測試
早期我們將linux發行版安裝到物理機中進行測試。當需要重新進行全量測試時不得不手動還原測試環境。之后改用了虛擬機,雖然能夠通過自動化的方式實現環境還原,但虛擬機的損耗較大,效率不高。
之后我們嘗試將環境制作成Docker鏡像,同時進行了如下的改進:
(1)通過Docker的“-v”選項,將主機目錄映射到容器中,實現多個容器共享測試代碼。測試代碼部署時間從2分鐘減少到10秒。
(2)將大粒度的執行時間較長的用例拆分成為若干個小用例。
(3)利用容器并發執行測試。
(4)使用Dockerfile梳理產品依賴包和編譯軟件的安裝。
編譯系統測試是用戶態的測試,非常適合使用Docker進行加速。如果需要針對某一個linux發行版進行測試,可以通過Docker快速部署的特點,將所有的資源快速利用起來,從而達到加速測試執行的目的。
8.2.linux外圍包測試
外圍包包含動態鏈接庫文件和常用的命令行工具,屬于linux操作系統的中間層,其上運行著應用程序,其下由linux內核支撐。起初的外圍包測試采用串行執行,效率不高。同時受到環境污染的影響,容易產生軟件缺陷的誤報。在改進方面,我們首先通過Dockerfile基于rootfs制作一個Docker鏡像,然后通過Docker-compose工具實現測試用例的并發執行。
以下是改進前后的對比。
改進前 |
改進后 |
每套環境獨占一臺主機,主機利用率不高。 | 多套環境可以在同一主機上部署,可以更有效利用主機資源。特別是在主機資源昂貴的情況下,可以節省很多成本。 |
測試串行執行,因為環境污染問題測試任務不易并發。 | 通過Docker進行測試任務隔離,可以并行執行測試,提高了cpu利用率。 |
環境釋放時清理工作依賴于程序員的技能。在每個測試用例中有一個cleanup函數,負責資源回收和環境恢復。如果程序員編程技巧不高的話,可能會造成資源回收不徹底,測試環境會受到污染。 | 環境釋放時清理工作由Docker接管,當執行完任務后,可以刪除容器。即使不寫cleanup函數,也可以實現資源的回收。 |
無法解決多個外圍包的環境污染問題。當連續執行多個測試時,有部分測試無法通過,而單獨執行這些測試時又能夠通過。這通常是由于測試環境污染造成的。 | 容器可快速啟動與關閉,每次都是清潔的環境。 |
外圍包編譯環境不易統一,導致測試結果不一致。 | 通過鏡像保存編譯環境,確保環境統一。 |
測試網絡包時需要至少兩臺主機,分別部署服務端和客戶端。 | 測試網絡包時只需要在同一臺主機中啟動兩個容器來部署服務端和客戶端。 |
9.通過Docker進行測試加速的原理
Docker本身并不會直接加速測試執行。在串行執行測試時,在容器中執行測試反而會帶來約5%左右的性能衰減。但我們可以充分利用Docker快速部署、環境共享等特性,同時配合容器云來快速提供所需的測試資源,以應對測試任務的峰值。如果忽略環境部署時間,當每個測試用例粒度無限小并且提供的測試資源無限多時,測試執行所需的時間也就無限小。
10.總結
很多測試任務可以利用Docker進行改造,讀者可以根據項目自身的特點,因地制宜的使用Docker進行測試能力的改造。
來自:http://www.infoq.com/cn/articles/docker-lead-test-innovation