持續交付探索與實踐(二):自動化工具鏈建設

g發表於2022-01-24

一、前言

上一篇介紹了我們是如何通過建立靈活、緊密的交付流水線來解決各業務線交付過程中的不順暢及資訊不透明等問題的。如果說流水線的引入帶來了汽車生產效率的第一輪革命性提升,那麼汽車生產效率的第二輪革命性提升則是由生產線的機械化升級所帶來的。類似的,在有了良好的研發過程流程化支撐之後,我們也需要將流程中的各類事務和活動儘可能的自動化,以便解放人的雙手,提升研發過程效率。下面我將主要從測試自動化、通知自動化、配置自動化這3個方面概要的介紹下我們在自動化這一塊的實踐。

自動化工具鏈建設

二、測試自動化(解放雙手,測試提效)

2.1、自動化框架搭建

通常來講,自動化測試可以分為單元測試、介面測試、UI測試這三個層面。下層測試用例的成本(包含程式碼維護成本、測試準備成本和執行時間成本)會低於上層測試用例,如下圖所示:

自動化分層

越往上越靠近業務和終端使用者,但與此同時,執行起來成本也越高、速度也越慢、投入產出比也越低。因此行業內最佳實踐往往是加大底層單元測試的佔比,再配合一定的介面自動化及UI自動化加以補充,單元、介面、UI自動化測試的佔比整體約為7:2:1,我們總體上來說也遵循了這樣的實踐,下面簡要介紹下每一層我們的實現方案。

UI層

UI自動化框架初期我們選用的是Uiautomator2,其底層基於Google Uiautomator,提供了一系列便利的 python 介面,相比Appnium等工具會更加輕量級,穩定性和可擴充性也更佳,其工作原理如下:

Uiautomator自動化

python端:執行指令碼,往移動端傳送HTTP請求

移動裝置:安裝atx-agent,啟動Uiautomator2服務進行監聽,解析收到的HTTP請求,轉換為Uiautomator2的程式碼進行操作。

使用Uiautomator2可以很便捷的編寫python指令碼來實現app的自動化用例,我們用這種方式實現了大部分的用例。但對於一些流程較複雜、變化相對頻繁的業務功能來說存在問題,比如:

  • 因業務需要增加了新的告警/提醒彈窗,而我們沒有事先獲知並在用例中進行相應的處理,就會導致用例執行中斷;
  • 某一些頁面做了調整,雖然對應的按鈕仍然在介面上,但是原先的定位方式已經失效。

為了解決上述問題,我們引入了Espresso,它是google官方提供的UI自動化框架,相比Uiautomator2,它可以和被測專案的程式碼有一定的互動,可以直接呼叫被測專案中封裝好的函式來實現更多的擴充,我們主要用其來覆蓋一些需要有複雜互動的用例,以便保障用例的穩定性。針對上面提到的問題,相關的解決程式碼如下:

espresso自動化 espresso自動化

而對於一些遊戲業務,普通的頁面元素校驗方式不能很好的滿足,所以我們又引入了Airtest增加了對應的影像識別的能力。這樣,最終形成了目前的這套Espresso+Uiautomator2+Airtest的開源UI自動化解決方案。

介面層

介面測試我們選用的是robotframework框架,它有著非常豐富的庫,同時也方便自定義library進行擴充,我們在原有基礎上增加了HTTP Library、NSQ Library、MC Library、Redis library、Database library等擴充套件庫支援了業務所需的各類操作和校驗;同時將用例體及相關配置進行了分離,實現了資料驅動,提升了用例的可重用性和可維護性,其整體架構如下:

robotframework架構圖

除了針對後端介面本身的測試,APP客戶端對後端介面的容錯也是很重要的一個點,若客戶端對後端介面未做好容錯處理,則很可能由於後端介面的返回異常、或者後端介面改動未能知會客戶端導致業務異常甚至是APP崩潰的情況,我們通過整合自動化平臺及YAPI介面管理平臺實現了介面容錯性校驗的自動化,整體方案如下:

app容錯性測試自動化

1、app測試包實現支援指定介面的特定開關,開關開啟後對應的介面請求轉而指向YAPI平臺的mock server

2、YAPI平臺的mock server會事先根據介面協議自動批量生成mock規則,每次收到請求時從mock規則池中輪詢並返回

3、自動化平臺執行對應的APP UI自動化用例,到特定步驟時開啟開關,使得對應介面的response從mock規則中獲取

以上方案相比業界普遍採用的結合monkey的方案有以下2個優點:

  • 用例排程和執行可以通過自動化平臺進行更靈活的控制,比如針對某個版本改動內容涉及的介面進行重點驗證,能在短時間內儘可能的覆蓋更多的場景;
  • 介面相關資訊管理統一化和配置更新及時化。由於整個部門的介面資訊的管理配置本身就採用了YAPI平臺,所以當有相關介面改動時就能第一時間得知,且通過Mock server可以很方便的定製和修改各類mock規則。

當然,該方案也有對應的缺點,就是需要有一定的用例維護工作量。

單元層

單元層我們選用的是junit框架,由各專案的研測同學共同維護,同時我們也會結合jacoco進行覆蓋率的檢測,最終的測試資料及報告會直接在持續交付平臺上展示。相關技術方案與細節與業界的實踐無太大差異,這裡就不再贅述。

 

2.2 自動化實施策略

在實現了上述自動化測試的能力之後,需要更合理更聰明的利用好這些自動化能力,以便最大化的發揮其價值,同時又儘可能的達到質量與效率之間的平衡。下面介紹一下我們在自動化執行策略優化和落地推動等方面所做的一些改進:

1)統一執行指令碼

原先各專案執行指令碼均相對簡單,我們執行的方式是直接將對應的單元用例執行命令體現在對應的junit job中,但是隨著業務的發展,單元用例的增多,各組各專案都出現了更多定製化的要求。比如有些專案的部分用例還不穩定,只希望跑特定模組的用例;有些專案需要特定的clean或build引數,這就導致了我們測開團隊出現了大量的配置和維護成本。

所以我們我們制定了統一規範,要求大家把各服務對應的單元執行指令碼統一寫在命名為cirun.sh的指令碼中並存放在專案倉庫的根目錄;通過這種方式就實現了用例呼叫指令碼和具體執行命令的分層,將執行指令碼的維護工具下發給了具體的業務團隊。對於持續交付平臺來說,不管具體的單元用例執行命令和執行引數如何,只需要統一執行cirun.sh指令碼即可;而對於各業務方來說,執行,單元用例的執行範圍、引數發生變化時,自行修改自己專案倉庫下對應的cirun.sh指令碼即可,不用擔心配置出錯而導致其他專案也無法正常執行,同時也方便對構建指令碼進行版本控制。

2)緊跟新功能開發進度

保持測試用例與新功能開發同步更新,可以給新功能提供及時的質量反饋。因為如果只是不斷滯後性的補充用例,那麼自動化測試的覆蓋可能一直落後於功能開發,無法起到全面的質量保護網的作用,大大降低了自動化的價值。

我們在這方面的實踐方案是設定自動化用例覆蓋率檢查點,我們基於jacoco進行二次開發實現了細化到類和方法粒度的程式碼覆蓋率檢測,同時通過在研發流程中設定對應的檢查點,判斷當前特性分支覆蓋率如果低於主幹分支的覆蓋率時,則進行阻斷,以此來保證用例更新與新功能開發的同步。

單元測試覆蓋率檢測

3)堅持質量重於數量

自動化用例質量低下會導致用例結果的不可信,而且這種用例本身的質量問題所導致的失敗會大大增加我們的無效投入,也會令大家慢慢失去對自動化的信心,甚至可能出現破窗效應,逐漸對失敗的自動化用例視而不見。所以,我們對所有的自動化構建都設定了通過率100%的質量閥,未達到則無法進入下一步流程。同時,我們也會有相應的工具去定期檢測每個服務的無效用例,以此來保障用例的整體質量。

單元測試通過率檢測

額外提一下,這裡並不是說用例的數量完全不重要,我們對覆蓋率也是有一定要求的,只是說我們沒有對每個團隊定義一個硬性的、統一的覆蓋率目標。我們這邊的操作方式是由質量團隊和研發團隊一起,根據不同的業務特性來確定每個專案都有哪些是核心模組,然後把這一部分模組的覆蓋率做到極致,也就是達到100%的覆蓋率。

4)提升自動化執行次數

這裡並不是指在同一場景下重複執行多次測試用例,而是指在多個不同的場景中重複利用這些自動化用例。比如開發人員在push程式碼後、在合入到整合分支後均執行對應用例,而不僅僅只是在正式提測前才執行一次用例。以便在不影響主流程效率的前提下,將自動化用例的價值最大化。

提升自動化執行次數

5)充分利用夜間時間和資源

我們的實踐方案是:自動檢測當天有程式碼變更的所有專案和分支,並在夜間閒時進行全量構建,並通過郵件的方式將結果傳送出來,使得開發人員第二天早上一上班就能收到針對前一天工作的整體質量報告,以便於及時跟進相關問題並進行修復,避免問題不斷堆積延後,導致修復成本的增加;同時我們也會對所有專案master分支的用例(穩定用例)進行定期構建,以便儘早發現一些不穩定因素,提升用例的整體質量。

夜間自動化測試

6)讓開發成為第一使用者

即儘可能的將對應的自動化測試前置到研發環節中去執行,將其作為研發自測的手段之一,而不是僅僅作為測試人員用來驗收開發人員工作質量的工具。

三、通知自動化(一旦完成,立即反饋)

有些時候,雖然我們在各個研發環節內部做了足夠多的優化,但是跨環節的協作可能還是存在大量的流轉與溝通成本,從而導致組織之間的穀倉困局,如下圖所示:

組織間的穀倉困局

為此,我們建立了相應的自動化通知機制。同時,結合通知內容或載體上的互動確認來實現接收到通知後的確認和反饋,從而真正的實現“一旦完成,立即反饋”。目前我們的自動通知從通知方式上主要分為2類:

3.1  郵件通知

郵件通知一般用於涉及大量資訊並且需要留檔的通知。比如發版前的驗收通知,我們通過在郵件中展示app包二維碼,能讓產品、測試等同學很方便的下載APP進行最終的驗收體驗;通過需求列表及測試結果、遺留問題等資訊的聚合展示又能直觀的看到有哪些需求進入了版本以及整體的質量風險如何。

郵件自動化通知

3.2  企業微信機器人通知

這種一般應用於需要被通知人及時響應的通知:比如需求提測需要介入、構建失敗需要跟進處理等等;通過將關鍵資訊彙總展示能讓被通知人第一時間瞭解需要跟進事項的詳情,通過一些互動連結又能讓大家很方便的跳轉到對應系統上進行相應的操作。

企業微信機器人

四、配置自動化(降低成本,減少出錯)

除了前面提到的流程流轉之外,整個交付過程中也涉及到不少的配置動作會耗費一定的精力且容易出錯,比如程式碼稽核的配置,釋出專案的配置等。為了減少使用者的配置成本,我們在配置自動化方面也做了不少改進,下面我拿2個案例介紹下我們在這方面的實踐。

4.1  程式碼審查標籤雙向同步

目前我們的持續交付平臺在研發階段和測試階段都有設定相應的code review確認節點(分別對應程式碼初審和程式碼終審),需要對應的稽核人確認完成程式碼稽核之後才能流轉到下一步。但是實際操作過程中存在一個問題:就是持續交付平臺雖然設定了相應的確認點,但是沒法進行稽核過程的支撐,這就導致稽核人員要先去gitlab上進行程式碼稽核,然後再回到持續交付平臺進行確認動作,比較不便。

為了解決這個問題,我們結合gitlab api和webhook實現了程式碼稽核標籤的雙向同步:當稽核人在gitlab對應的merge request打上稽核通過的標籤後,webhook會監聽到對應動作並同步狀態給持續交付平臺。 反過來,如果稽核人員在持續交付平臺上進行稽核通過的操作,系統也會呼叫gitlab api在對應的merge request上打上相應的標籤。這樣,在不改變使用者操作習慣的前提下,滿足了交付流程中的程式碼稽核規範要求。

gitlab webhook標籤同步

4.2  智慧化釋出配置中心

另一個案例是關於釋出專案配置的。我們整個研發過程中會涉及到多次的部署行為,比如測試環境的部署、整合環境的部署、線上機器的釋出等等,不同的環境涉及到不同的機器叢集和不同的釋出配置;而且,當環境有所變動時,對應的配置也需要進行調整。而這些配置資訊的確認過程是極為枯燥和繁瑣的。為了解決這個痛點,我們主要做了2點改進:

1)首先是配置資訊的智慧填充:比如我們通過打通內部的RMS釋出平臺,自動獲取最近一次的釋出配置引數進行預填充;並且根據程式碼變更情況,在釋出選項中優先展示可能要釋出的專案,使得開發人員每次釋出時無需從0開始將全部引數配置一遍,僅需核對自動推薦的配置資訊並根據實際情況進行少量調整即可;

2)其次是視覺化配置中心的建立:我們通過將各個環節的配置資訊進行聚合展示,並對異常配置做顯性化的提示,能讓大家很直觀的看到整體的配置情況以及所存在的問題。

通過以上措施,將各類配置化繁為簡降低人工成本同時,也儘可能的避免了因為配置出錯而導致的過程損耗。

智慧化釋出配置中心

五、結語

以上就是我們在自動化方面的所作的一些探索和實踐。由於篇幅的關係,本次主要是對整體實踐方案進行介紹,沒有對其中的一些細節進行過多的展開,後續有機會的話再進行鍼對性的介紹。

下一篇預告:持續交付探索與實踐(三):指標度量體系搭建

 

相關文章