持續集成:從六個層次加速測試執行
在持續集成領域,一個產品的發布往往都有自己的過程周期(lifecycle),大體都會劃分為:構建->部署->測試->發布等幾個重要階段,其中測試是發布產品前不可或缺的重要階段,是產品質量的保證。而能讓持續集成奏效,除了要求測試腳本更充分健壯,還要求測試腳本運行得更快更好。這點對于小型項目而言可能顯得無關緊要,畢竟大多小項目的測試腳本不過百條,驗證點不過千“點”;但對于一個大型項目而言,測試代碼源文件可能成百上千,執行完所有的測試可能要等很久,而苦等之后的結果卻可能是滿眼的failure, 于是如果提高測試執行速度成為迫切需要解決的問題,試想把測試階段從2小時壓縮到1小時,再從1小時壓縮到30分鐘,每次時間壓縮帶來的不僅是技術人員本身的成就感,更是對整個產品發布過程體驗的改善。
那么如何加速測試的執行呢?提起速度,我們立馬可能聯想到“性能”調優的步驟:先進行tuning,然后找到問題的瓶頸所在,最后逐個擊破。本文暫不討論如何進行這些步驟, 而是基于C++和Java為語言案例,TestNG和Google test為測試框架,Jenkins為持續平臺做分析,從以下六個層次提出提高測試執行的一般方法:
硬件資源層次
工欲善其事必先利其器,提高硬件(CPU、內存、磁盤等)配置是改善執行速度的“硬”方法,硬件資源的優化不應僅僅局限在單機自身的各項指標提升,在需求不斷提高的情況下,可以考慮實施虛擬機、分布式集群等方式來進一步獲取更優的硬件資源,當然,涉及分布式執行時,可以借助以下持續集成平臺層次的“軟”實施來共同作用。
另外,在硬件資源緊張的情況下,不同項目或者不同團隊可能不得不復用一套測試環境,造成可利用資源更為緊張,此時可以錯開時間測試(例如A項目組測試定時在凌晨0點啟動,B項目組定時在凌晨2點)以提高速度。
語言編碼實現層次
測試代碼本身也是代碼,顯而易見,如果代碼編寫時注重效率,速度上肯定有所收益。這點可能需要“糾結”于一些日常的編碼細節:例如Java中Stringbuffer和Stringbuilder的比較;C++中是i++和++i的比較。這種語言層次提高效率的文章書籍很多,這里不做過多描述。在語言編碼層次上最重要的不是這些語言細節,而是避免一些消費時間的測試代碼設計,減少不必要的耗時操作,例如以下幾點:
(1) 冗余的日志信息,不合理的日志級別設置等
輸出日志帶來的磁盤頻繁訪問必然讓速度下降,所以在保證日志信息充足的前提下,盡量減少日志,或者只記錄失敗測試的日志(畢竟對于測試者而言很少去關注成功日志),可以讓測試加快。
(2) 不合理的等待
用戶執行完某個操作,必須等待某條件的發生(例如DB里面插入一條新數據)進而執行后續動作是測試中經常面對的場景,那么等待多久成為需要考慮的問題,假設用TimeUnit.MINUTES.sleep(1)等待一分鐘,在10秒即可滿足條件的場景下浪費的就是50秒,所以這里必須去考慮合理sleep的時間來兼顧對資源的消耗和運行速度的影響,同時在等待方式上也可以考慮是采用循環短時間條件等待或異步通知的方式去進行。
(3) 用例的過程
先執行完所有測試步驟,然后做對所有步驟做一次性校驗,還是做完一步校驗一步,這兩種方式的速度在不同場景下有所不同,所以需要權衡;相類似的,對于需要獲取DB連接的用例,是每條都執行獲取DB連接然后釋放連接,還是所有用例執行之前獲取連接,所有case執行完之后釋放連接也會對執行速度有所影響。
構建測試腳本層次
對于一個大型項目,源文件的數目龐大或依賴的dependency過多導致代碼編譯占用大量時間,如何提高編譯代碼的速度?除了使用更好的磁盤,注重代碼編寫時對編譯速度的影響,還可以針對不同的語言采取不同的有效策略,例如針對C++, 使用make命令編譯項目時,可以加上參數-j來并行編譯項目。-j參數的含義可以參考下文:
-j [jobs], --jobs[=jobs]
指定同步運行的作業(命令)的數量。如果有一個以上-j選項,那么只有最后一個有效。如果-j選項沒有參數,那么編譯過程就不會限制能夠同步運行的作業的數量。
需要說明的是,編譯過程可能要求特定的順序而導致并行編譯失敗,如果遇到這種問題,可以先并行、后串行(去掉-j)重復執行一次以解決。
而對于java,Maven 3 開始支持并發build,提供了以下幾種常見方式:
mvn -T 4 clean install # Builds with 4 threads
mvn -T 1C clean install # 1 thread per cpu core
mvn -T 1.5C clean install # 1.5 thread per cpu core
同時使用maven管理java項目常出現時間消耗在依賴jar的下載上,此時可以檢查是否有冗余失效的repository配置、較長的下載timeout時間設置、所選擇repository的連接速度等,甚至在不同測試環境下可以使用 profile來管理repository來加速測試腳本構建。
posted on 2014-06-25 11:34 順其自然EVO 閱讀(176) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄