張挺:測試開發的技術 - 引子

張挺:測試開發的技術 - 指令碼化

張挺:測試開發的技術 - 自動化

張挺:測試開發的技術 - 持續整合化

張挺:測試開發的技術 - 服務化

張挺:測試開發的技術 - 工具化

張挺:測試開發的技術 - 視覺化

持續整合化

持續整合包含的範圍也很廣闊,然而很多人認為持續整合不就是搞個jenkins嘛,這還用講?我就遇到過這樣的質疑,有面試官認為持續整合很簡單,沒什麼價值,還替我總結了“那你就是裝了個jenkins,配了兩個job唄?”這樣的認識過於片面。

我來談一談我對持續整合的認識與理解,以及其技術要點。

持續整合做的事是,在自動化的基礎上更進一步,讓測試不需要人手工來觸發。

但,這絕非把觸發自動化測試的指令碼移動到jenkins上那麼簡單。這裡涉及到了很多麻煩的問題,今天挑其中四個主要的來講:測試環境的管理、持續整合工具本身的安裝配置與維護、待測軟體和測試指令碼的分支管理及各分支測試策略的制定、持續整合工具與其他工具的整合。

一、測試環境的管理

為什麼測試環境的管理也成了個問題呢?在做不涉及持續整合的自動化測試時,我們是人工搭建和確認測試環境準備好了,才開始觸發自動化測試的。而持續整合要減少人工干預,第一步就是讓測試自動觸發,而不是人工觸發,那麼問題就來了,觸發測試時,測試環境是否已經準備好了?

為了解決這個問題,我們要管理測試環境,管理測試環境有兩種主流做法。

1.第一種是“羊群法”

。持續整合的流水線(pipeline)從待測軟體原始碼開始,先用原始碼裝出一個待測軟體的環境。然後再開始在這個新安裝出來的環境上做測試。這種方法通常應用於雲計算環境中,因為可以快速建立相同的虛擬硬體。此時,測試環境就像羊群,每一隻都很相似,飼養時不需要特殊對待其中某一隻羊。羊群裡的羊,我們沒有給他們起名字,而是動態命令,比如env_001,env_002,

2.第二種是“寵物法”

,使用工具或手工維護一系列可以用的測試環境,人工保證這些環境一直都處於能用的情況下。持續整合直接不搭建環境而針對這些人工維護的環境來做。此時,測試環境就像寵物,每一隻都有各自的個性(比如伺服器硬體不同),而且測試人員還喜歡給環境起寵物名字,比如我們在諾基亞曾經用過一些名字來稱呼那些測試環境:Venus,Mars,等等。還要經常由專人伺候這些寵物,比如我負責維護Venus,你負責維護Mars。誰要用Venus得通知我一聲才能用。

通常,當待測軟體的安裝耗時較短、安裝操作較簡單時,我們選擇第一種方法,反之選第二種。舉個例子,在諾基亞我們安裝一臺通訊裝置上的測試環境,非常麻煩,要從作業系統開始裝一直到裝好我們的待測軟體。耗時3-8小時不等,還有失敗機率。當時我們主要選第二種方式,人工維護裝置,且有冗餘裝置以備不時之需。後來,我們架構改成了x86的雲架構,不再需要通訊裝置,直接改成在雲平臺上虛擬裝置,此時,我們改成了使用第一種方法(其實在通訊裝置的自動化成熟後就改成了第一種方法,但環境準備仍然有時會失敗)。此時,搭建環境非常的簡單,只需要20-60分鐘時間,且配置檔案極其簡單。

二、持續整合工具本身的安裝配置與維護

持續整合工具,比如jenkins本身的安裝、配置、維護其穩定性,並沒有想象中的容易。如果使用者少,自然簡單,使用者越多,這個任務難度越大。我一個人用的話,我甚至可以要用的時候開,不用的時候關掉。而如果有兩百個人使用我這臺jenkins,即使我要升級它的版本,我都得考慮我是做熱備份還是冷備份,備份完了才能升級。

覺得jenkins搞搞很簡單的朋友們請看以下這些問題:

主節點(master node)裝在哪兒,硬碟用多大,可以擴充套件嗎,幾個cpu,多少記憶體,使用者怎麼鑑權,使用者許可權怎麼控制,外掛裝哪些,怎麼升級jenkins版本,怎麼升級外掛版本,日誌把磁碟控制元件佔滿了怎麼辦,jvm引數配哪些怎麼配,用哪種安裝方式(rpm?war?docker?),master掛掉了怎麼處理,從節點(slave node)裝哪兒,要動態建立動態銷燬嗎,日誌存哪裡,怎麼監控各個slave資源使用情況,每個slave配幾個執行器(executor)效率最高,配到多少執行多少job會卡死,slave卡死了怎麼恢復,資料怎麼保證不丟,怎麼處理長期不用的job,怎樣清理沒用但佔用極大硬碟控制元件的檔案,怎麼給job合理分組,怎麼配置jenkins的https證書,怎麼配csrf token,怎麼用job觸發另一個job,怎麼把主要job的狀態集中展示,怎麼配時區和時間同步。等等。

看到上述一大堆令人頭皮發麻的問題之後,我們以後看到一個穩定運行復雜業務的jenkins時,就直到背後維護人員付出的努力有多大了。為了解決這些問題,我採用的方法是指令碼化。寫指令碼來處理各種麻煩事情。jenkins支援使用http api做簡單操作,也支援groovy指令碼來做複雜操作。這僅僅是工具本身帶來的麻煩的一半內容,另一半麻煩在持續整合工具與其他工具整合的時候才會出現。

三、待測軟體和測試指令碼的分支管理及各分支測試策略的制定

這裡,測試策略、分支管理模型都和持續整合關係極大。因為,我們如果要觸發一個持續整合任務(job)。那麼有三個層次的觸發方式:

1。手動觸發。測試人員開啟job點一下。

2。定時觸發。每天或每週到點了自動觸發。

3。透過服務端介面(hook,也有人直譯為鉤子。)觸發。提交程式碼到版本控制工具比如git後,由該工具的服務端比如github觸發job。

如果我們要做到3,那麼就要定義好在不同的程式碼分支上觸發不同的job或者pipeline。這裡問題就多了,程式碼要分幾個分支來管理,用哪種git flow模型,不同分支上觸發的job或者叫pipeline裡要包含哪些步驟,其中哪幾步是做測試,做什麼測試,怎樣判斷其透過與否,能否允許程式碼進入下一個分支的條件是什麼,hook傳送失敗怎麼辦,job應該觸發時jenkins不巧正好掛掉了怎麼辦,需要同時觸發多工來的特殊程式碼怎麼辦(比如一個微服務應用包括幾百個服務,需要並行部署,而不是一個一個部署,一個一個部署實在太慢了),在哪一個分支引入哪些第三方工具(比如程式碼掃描),在緊急情況比如需要緊急修復bug時怎麼跳過耗時很久的流水線步驟(pipeline stage)。怎麼控制各個job的許可權,避免job A誤刪job B的資料。等等。

這都是持續整合化要考慮的問題。所以就別說持續整合簡單了。這裡面很複雜的。

四、持續整合工具與其他工具的整合。

今天講的最後一點是工具整合。首先科普一個概念,jenkins的外掛一般不包含功能本身,功能本身大多數是由對應的軟體來提供的。比如jenkins上安裝了git外掛之後,不代表就能在jenkins上使用git了,我們哪臺slave要用git,就必須在這臺slave上安裝git。外掛只是起到一個介面和管理的功能。大家可能看過運維開發(devops,說句題外話,devops翻譯成運維開發實在不妥,因為devops是開發、運維、測試三者的交集,起名字的人直接把test從devtestops裡省略掉了。同理,測試開發這個詞把運維給省略了,但其實測試開發要掌握很多運維知識)的工具鏈,圍繞著jenkins由幾十種第三方工具可以整合上來。我們還可以自研一些工具,把工具化和持續整合化結合起來用。

然後,這裡有一個巨大的坑,值得我單獨起一段來強調。那就是:這些第三方工具和jenkins外掛,都有可能有Bug,而這些Bug誰來修?就只有我們自己修啦。千萬別覺得持續整合簡單,光這個修bug就夠喝一壺的了。有一些bug很麻煩,很難修,很隱蔽,危害很大。比如,我們目前遇到卻沒修的一個bug:jenkins上使用github的oauth鑑權的外掛,會在我們開啟任意job的url時,對整個jenkins所有job的許可權做檢查,檢查當前使用者有沒有許可權訪問這些job。當job很多的時候(我的測試jenkins最多的時候幾百幾千個job),jenkins就直接卡住了,jvm記憶體不夠用,然後cpu佔用100%,動都動不了了。誰說持續整合簡單的,很麻煩的。 所以有jenkins的付費版cloudbee,有專業公司來替使用者解決這些問題,但是那個價格嘛,高到足以勸退一般使用者。

持續整合平臺或工具的研發

正因為上述難點和cloudbee的高費用問題,導致了有條件的企業可能選擇自己研發持續整合工具,我之前諾基亞也有不少人想要研發各種各樣的持續整合工具。包括但不限於:用兩個jenkins master 一主一從做熱備;用jenkins+docker+zookeeper等一些工具來搭建master 節點叢集化且能動態新建銷燬的jenkins;在jenkins上面開發一層web平臺,底層仍然用jenkins 觸發job的完全自研平臺;從頭開發一個持續整合平臺,並且可以用jenkins master做它的slave,但這個和上一個區別在於,它還支援其他型別的slave(只可惜我未見到成品)。

要不要自研持續整合平臺或工具,我覺得主要取決於有多少資源。沒人沒資源硬要搞,是非常困難的。因為這些自研工具平臺會引出測試開發界最大的問題:測試指令碼/工具/平臺本身的質量問題。於是,我們遇到過為持續整合平臺開發持續整合測試的需求,這就變成套娃了。要解決這個問題,只有一個辦法,讓開發工具平臺的開發人員接地氣,自己使用這些工具平臺做業務測試,至少也要用自己的工具平臺來測試自己的工具平臺。