如何將bug殺死在搖籃里?
在歐洲中世紀(jì)的傳說中,有一種叫“人狼”的妖怪,就是人面狼身。它們會(huì)講人話,專在月圓之夜去襲擊人類。而且傳說中對“人狼”用一般的槍彈是不起作用的,普通子彈都傷不到也打不死它,只有一種用銀子作成的特殊子彈才能把它殺死。Brooks在他最著名的隨筆文章《No Silver Bullet》里引用了這個(gè)典故 ,說明在軟件開發(fā)過程里是沒有萬能的終殺性武器的,只有各種方法綜合運(yùn)用,才是解決之道。
那么在軟件研發(fā)過程中,哪怕沒有銀彈,如何用各種方法去解決這些“人狼”帶來的威脅呢?阿里巴巴在多年的研發(fā)過程中,又是如何對付這頭“人狼”?這一路走來,又有哪些方法和實(shí)踐沉淀?
1.阿里巴巴研發(fā)協(xié)同平臺(tái)介紹
阿里巴巴研發(fā)協(xié)同平臺(tái)(AONE)是阿里一站式智能研發(fā)協(xié)同平臺(tái),目前為阿里巴巴集團(tuán),下屬子公司以及生態(tài)合作伙伴提供從“需求->編碼->測試->發(fā)布->反饋”端到端的持續(xù)交付服務(wù),并解決研發(fā)過程中跨角色、跨組織、跨地區(qū)的協(xié)作問題,在此基礎(chǔ)上通過數(shù)據(jù)驅(qū)動(dòng)度量分析為組織效能提升提供決策依據(jù),目前這一平臺(tái)已經(jīng)上云對外提供服務(wù),稱為阿里云研發(fā)協(xié)同RDC。(以下簡稱為RDC)
?? 
上圖是整個(gè)RDC的業(yè)務(wù)框架,RDC采用微服務(wù)的架構(gòu),從規(guī)劃到運(yùn)營提供了業(yè)務(wù)全生命周期的服務(wù),眾多的服務(wù)造成了RDC的復(fù)雜度,另一方面作為一個(gè)面向用戶的平臺(tái),RDC又涵蓋了阿里三個(gè)層次的技術(shù)服務(wù)棧。
第一層,基礎(chǔ)資源層,包括idc機(jī)房、網(wǎng)絡(luò)設(shè)施、OS、Docker、數(shù)據(jù)庫等。
第二層,平臺(tái)服務(wù)層,包括中間件、調(diào)度層、應(yīng)用服務(wù)器等。
第三層,RDC研發(fā)協(xié)同平臺(tái),包括 項(xiàng)目、代碼、應(yīng)用、測試、交付、運(yùn)營的管理。
三個(gè)層次加起來涉及的核心應(yīng)用達(dá)50+,隨便一個(gè)風(fēng)吹草動(dòng)就會(huì)對系統(tǒng)的穩(wěn)定性造成影響,這些影響最終體現(xiàn)到面向用戶的RDC,因此好的質(zhì)量保障才能為用戶提供一個(gè)穩(wěn)定,高可用性的研發(fā)協(xié)同平臺(tái)。
2.質(zhì)量保障策略
總體采用 “事前預(yù)防”,“事中控制”,“事后總結(jié)改進(jìn)”的思想,主要做的三件事情:
?? 
- 測試驅(qū)動(dòng)持續(xù)交付
 
測試驅(qū)動(dòng)持續(xù)交付,每一次的持續(xù)集成和發(fā)布都從單元測試,API測試,集成測試,UI測試進(jìn)行自動(dòng)化測試覆蓋;具體包括:單元測試,集成測試,WebUI測試,移動(dòng)端UI測試,壓測,線上引流的API測試,線上冒煙測試。
- 線上質(zhì)量監(jiān)控
 
對線上質(zhì)量的保障,主要采用監(jiān)控的方式,希望一有問題就能及時(shí)發(fā)現(xiàn)解決,避免問題的大面積擴(kuò)大。主要包括:
(1) 機(jī)器監(jiān)控報(bào)警,業(yè)務(wù)數(shù)據(jù)監(jiān)控。
(2) 對線上運(yùn)行日志的聚合分析,發(fā)現(xiàn)存在的錯(cuò)誤。
(3) SLA數(shù)據(jù)質(zhì)量提升,將業(yè)務(wù)數(shù)據(jù)可視化,指導(dǎo)改進(jìn)方向。
(4) 面向業(yè)務(wù)的監(jiān)控和故障演練,通過對線上7*24的監(jiān)控提前發(fā)現(xiàn)問題保障系統(tǒng)的穩(wěn)定運(yùn)行。
- 研發(fā)質(zhì)量提升
 
通過代碼審核,集團(tuán)規(guī)約掃描,規(guī)范代碼和提升研發(fā)質(zhì)量。
3. 持續(xù)交付流程
?? 
上圖是測試驅(qū)動(dòng)的的持續(xù)交付流程,也是RDC各個(gè)應(yīng)用在發(fā)布時(shí)的持續(xù)交付流程,通過RDC的發(fā)布功能實(shí)現(xiàn)。
(1) 開發(fā)在變更(Change Request)中提交代碼后,觸發(fā)單元測試,檢查代碼中基本的邏輯問題,實(shí)踐中單測的覆蓋率和維護(hù)由開發(fā)同學(xué)自己保證,目前RDC核心應(yīng)用的單測行覆蓋率在50%左右。
(2) 部署測試環(huán)境,開發(fā)進(jìn)行自測,主要對新的功能進(jìn)行基本的驗(yàn)證。測試環(huán)境與生產(chǎn)環(huán)境完全隔離,具有獨(dú)立的網(wǎng)絡(luò)環(huán)境,單獨(dú)的數(shù)據(jù)庫和中間件等依賴環(huán)境。
(3) 自測完成后發(fā)布預(yù)發(fā)環(huán)境,由測試同學(xué)進(jìn)行集成測試,包括回歸測試和新功能的驗(yàn)證,以及對核心接口的小壓測。預(yù)發(fā)環(huán)境與生產(chǎn)環(huán)境在同一個(gè)網(wǎng)絡(luò)中,共享同一個(gè)數(shù)據(jù)庫,數(shù)據(jù)隔離采用邏輯隔離,但是它具有一個(gè)獨(dú)立的依賴環(huán)境,如獨(dú)立的上下游和中間件。
(4) 接著進(jìn)入Beta測試環(huán)節(jié),通過截取一部分生產(chǎn)環(huán)境的流量到Beta環(huán)境回放來對核心接口做進(jìn)一步的驗(yàn)證。Beta環(huán)境與線上環(huán)境完全相同,不同的是Beta環(huán)境不對外提供服務(wù)。
(5) Beta測試完成后,正式發(fā)布生產(chǎn)環(huán)境并對生產(chǎn)環(huán)境執(zhí)行冒煙測試。
以上是一個(gè)變更的生命周期,也是一次完整的持續(xù)交付流程。得益于RDC發(fā)布系統(tǒng)和RDC實(shí)驗(yàn)室的集成,我們可以在持續(xù)交付的流程中實(shí)現(xiàn)測試的卡點(diǎn),測試不通過,無法進(jìn)入下一個(gè)階段的發(fā)布。
4.測試技術(shù)和方法
以下內(nèi)容重點(diǎn)討論測試方法和實(shí)現(xiàn)方案,以及如何通過RDC完成持續(xù)交付,不涉及代碼實(shí)現(xiàn),部分服務(wù)也會(huì)在未來上云提供給外部用戶試用。
4.1 分層的自動(dòng)化測試
傳統(tǒng)的自動(dòng)化測試更關(guān)注的產(chǎn)品UI層的自動(dòng)化測試,而分層的自動(dòng)化測試倡導(dǎo)產(chǎn)品的不同階段(層次)都需要自動(dòng)化測試。在《google 測試之道》一書,對于google產(chǎn)品,70%的投入為單元測試,20%為接口、集成測試,10% 為UI層的自動(dòng)化測試。如下圖的金字塔形,越往上的投入越低,按照代碼統(tǒng)計(jì)的測試覆蓋率也越低。
?? 
4.2 測試框架
- 測試框架的選型
 
在開始RDC的自動(dòng)化前團(tuán)隊(duì)對其他測試工具有了一定的積累,各種流行工具,數(shù)據(jù)驅(qū)動(dòng),關(guān)鍵字驅(qū)動(dòng)工具,如Fitness,RobotFramework等,也調(diào)研過一些特定的測試工具如對http測試的Jmeter, Postman, SoapUI等。
這些工具普遍存在的一個(gè)問題是不夠靈活,工具本身比較重,調(diào)試麻煩;另一些比較輕量的工具又功能單一,針對性強(qiáng),無法作為一個(gè)測試框架使用,測試場景比較簡單時(shí)非常好用,一旦場景變復(fù)雜,就帶來了大量的維護(hù)工作。
其次也開發(fā)過一些看起來很高大上的框架,有前端有后端,目的是減少測試人員的coding工作,一鍵完成測試,看起來很高大上。 但實(shí)際的問題是測試人員的主要工作變成測試框架的維護(hù),最后的結(jié)果是業(yè)務(wù)綁定太強(qiáng),無法推廣,而自己的用例覆蓋率也沒有上去。
最后選擇了TestNG作為主測試框架,其他的功能全部交給RDC完成。選擇TestNG的理由:
(1)是靈活,作為程序員可以用代碼實(shí)現(xiàn)靈活的場景組織和功能,只要稍微二次開發(fā)一下。
(2)是跟很多框架一樣有Before,after,listener的概念,基于單元測試卻比junit強(qiáng)大,對場景的準(zhǔn)備,還原,清理都能較好的處理。
(3)使用java,也許不是好的測試語言,但是團(tuán)隊(duì)的技術(shù)儲(chǔ)備java是強(qiáng)項(xiàng),擁有豐富的開源測試庫,能夠完成單測,API,集成測試,WebUI,移動(dòng)UI的測試;另一個(gè)原因是RDC本身也采用Java開發(fā)。
(4)缺點(diǎn)是冗余,作為一個(gè)測試框架,要實(shí)現(xiàn)測試比其他的測試框架要多一些代碼。但是作為一個(gè)需要長期維護(hù)的測試工程,這些冗余也還可以接受。
- 基于TestNG的測試框架
 
采用分層的方式
?? 
如圖所示,整個(gè)測試框架分為四層,通過分層的方式,測試代碼更容易理解,維護(hù)起來較為方便。
第一層是基礎(chǔ)測試庫:包括selenium,macaca,ssh庫,httpclient,cli庫等。
第二層是服務(wù)層,相當(dāng)于對測試對象的一個(gè)業(yè)務(wù)封裝,如http的測試,是對遠(yuǎn)程方法的一個(gè)實(shí)現(xiàn),對于頁面測試,是對頁面元素或操作的一個(gè)封裝。
第三層測試用例邏輯層,該層主要是將服務(wù)層封裝好的各個(gè)業(yè)務(wù)對象,組織成測試邏輯,進(jìn)行校驗(yàn)。
第四層測試場景,將測試用例組織成測試場景,實(shí)現(xiàn)各種級(jí)別cases的管理、冒煙,回歸等測試場景。
測試執(zhí)行
隨著測試用例的豐富和完善,測試時(shí)間會(huì)越來越長,我們的原則是盡量讓所有的cases在15分鐘內(nèi)執(zhí)行完,讓整個(gè)發(fā)布流程能快速迭代起來,在實(shí)踐中采用了兩個(gè)方法:
測試調(diào)度:主要用于集成測試和UI測試,因?yàn)檫@兩個(gè)是對一個(gè)系統(tǒng)整體進(jìn)行測試,RDC采用微服務(wù)的架構(gòu),整個(gè)RDC應(yīng)用被拆分成十幾個(gè)微應(yīng)用,如果一個(gè)應(yīng)用發(fā)布后測試過程中,另一個(gè)關(guān)聯(lián)應(yīng)用也發(fā)布了,那么這次測試結(jié)果的意義就不大。
因此在執(zhí)行中加入了調(diào)度機(jī)制,對關(guān)聯(lián)應(yīng)用進(jìn)行調(diào)度,比如A、B是兩個(gè)互相關(guān)聯(lián)的應(yīng)用,A應(yīng)用發(fā)布后正在進(jìn)行測試,B應(yīng)用發(fā)布,這時(shí)我們的調(diào)度程序會(huì)將測試中斷,然后B應(yīng)用發(fā)布完成后,重新開始測試,最后將結(jié)果返回給A、B兩個(gè)應(yīng)用,同時(shí)完成卡點(diǎn)。
分布?xì)w并: 在測試集合中我們將用例進(jìn)行組合,保證每個(gè)測試集合都在15分鐘內(nèi),一旦發(fā)現(xiàn)時(shí)間增加則將測試集進(jìn)一步拆分,然后將這些測試集并行執(zhí)行,最后將整個(gè)結(jié)果歸并,既能壓縮時(shí)間,又能實(shí)現(xiàn)報(bào)告的統(tǒng)一。 所有用例在docker中執(zhí)行,動(dòng)態(tài)的分配測試資源。
4.3 單元測試與依賴隔離
關(guān)于單元測試的投入產(chǎn)出不同的公司團(tuán)隊(duì)有不同的認(rèn)識(shí),實(shí)踐中認(rèn)為單元測試的主要意義在于最低成本的發(fā)現(xiàn)問題,尤其對于代碼的改動(dòng),相比集成測試階段的問題更容易定位,并且良好的單元測試習(xí)慣能夠使開發(fā)在編寫代碼時(shí)更全局的考慮問題。單測中主要需要解決的問題是外部依賴的隔離。
外部依賴的隔離:Mock和Stub
由于單測主要檢查自身代碼,因此需要處理對外部依賴的隔離,常用的外部隔離方式主要有Mock和stub兩種方式,這兩種方式的主要區(qū)別是Mock關(guān)注對代碼邏輯的驗(yàn)證,Stub關(guān)注狀態(tài)的驗(yàn)證。單元測試中采用Mock的方式,原因是Mock能快速的實(shí)現(xiàn)單測邏輯,執(zhí)行速度快,而Stub一般需要搭建復(fù)雜的模擬環(huán)境,維護(hù)成本較高。
隔離工具:Powermock+Mock
通過這兩個(gè)工具可以Mock出 1. 構(gòu)造函數(shù)、2. 靜態(tài)函數(shù)、3.枚舉實(shí)現(xiàn)的單例、4.選擇參數(shù)值作為函數(shù)的返回值、5.在調(diào)用的mock方法中,改變方法參數(shù)的值。
使用中Mockito可以滿足大部分的需求,但是它的實(shí)現(xiàn)機(jī)制是使用cglib來動(dòng)態(tài)創(chuàng)建接口的類的實(shí)例,這種實(shí)現(xiàn)方式不能用于構(gòu)造函數(shù)和靜態(tài)函數(shù),因?yàn)檫@兩個(gè)需要使用類的字節(jié)碼(比如使用javassist),所以結(jié)合PowerMock一起。
單測用例
使用TestNG的注釋方式組織用例,通過Assert來校驗(yàn)邏輯數(shù)據(jù)是否期望。
接入RDC和覆蓋率收集
在RDC的【變更】中配置【持續(xù)集成】實(shí)驗(yàn)室,在實(shí)驗(yàn)室中配置單元測試實(shí)驗(yàn)室,RDC會(huì)監(jiān)控代碼提交事件,一旦提交則觸發(fā)單測的執(zhí)行。
關(guān)于測試評(píng)價(jià),目前也沒有特別好的評(píng)價(jià)體系,所以最常用的還是代碼覆蓋率,在工程的pom.xml中引入cobertura,排除不需要計(jì)入的第三方class,RDC單測實(shí)驗(yàn)室中的代碼覆蓋率工具會(huì)自動(dòng)統(tǒng)計(jì)覆蓋率。目前RDC的行覆蓋率在50%,據(jù)了解行業(yè)內(nèi)做的好的一般在68%左右。
4.4 大集成測試
集成測試是整個(gè)持續(xù)交付中最重要的階段,穩(wěn)定可靠的集成測試能夠減輕測試工程師的壓力,其次能促進(jìn)開發(fā)和測試之間的相互信任,形成良好的互動(dòng)。集成測試一般采用API的方式,在預(yù)發(fā)階段進(jìn)行,選擇這一階段的原因是環(huán)境較為穩(wěn)定,測試發(fā)現(xiàn)的問題能真正反映系統(tǒng)的問題。
集成測試的方式
如上面分層測試的框架中,采用httpclient作為工具,將遠(yuǎn)程的http服務(wù)封裝成本地服務(wù),再進(jìn)一步實(shí)現(xiàn)測試用例和測試場景。
集成測試規(guī)模
集成測試按照集成的規(guī)模,分為小集成測試和大集成測試,小集成測試一般是在某幾個(gè)系統(tǒng)之間進(jìn)行集成,大集成測試在整個(gè)系統(tǒng)中進(jìn)行,這兩個(gè)主要區(qū)別是測試覆蓋和測試時(shí)間,我們使用最在靠近用戶UI一層的API進(jìn)行大集成測試,這一層更能體現(xiàn)真實(shí)的體驗(yàn),能用最少的投入產(chǎn)生最大的價(jià)值。測試時(shí)間通過測試調(diào)度控制,每一個(gè)子系統(tǒng)發(fā)布時(shí)檢測是否有測試進(jìn)行,如果有則停止再重新觸發(fā)。
接入RDC
在RDC應(yīng)用中有【測試驗(yàn)證】,選擇【添加驗(yàn)證點(diǎn)】,設(shè)置階段為預(yù)發(fā)集成測試(也可選擇其他階段),同時(shí)在此處可以設(shè)置卡點(diǎn)的條件,如設(shè)置測試通過率99%,當(dāng)你的測試通過率小于這個(gè)數(shù)字時(shí)在發(fā)布流程的預(yù)發(fā)測卡點(diǎn)中將會(huì)報(bào)失敗,防止將測試驗(yàn)證不通過的代碼發(fā)布到線上。
4.5 云瀏覽器上的UI自動(dòng)化測試
UI測試是一個(gè)很繁雜的事情,投入產(chǎn)出比不高,UI測試最大難點(diǎn)在穩(wěn)定性和維護(hù)性方面,因此我們在UI功能測試當(dāng)中只覆蓋主流程和最基本的頁面檢查,主要對主流程進(jìn)行覆蓋,如增、刪、改、查等這些出錯(cuò)會(huì)造成系統(tǒng)不可用的功能進(jìn)行覆蓋。
UI測試的實(shí)現(xiàn)
UI測試采用selenium,通過selenium時(shí)將頁面元素和功能進(jìn)行抽象,稱為PageObject,如頁面的增加按鈕,查詢按鈕的封裝作為PageObject放在服務(wù)層,而測試邏輯層則用這些服務(wù)組裝成需要的測試邏輯。值得分享的是使用selenium做UI測試時(shí)盡量采用css,css定位較為準(zhǔn)確,相比xpath定位速度較快,對比的結(jié)果是采用css比xpath速度最快能到20倍,尤其在IE上。
UI測試另一個(gè)比較麻煩的事情是兼容性,由于各類瀏覽器的快速迭代經(jīng)常造成selenium連接瀏覽器、獲取元素失敗。因此我們對selenium-grid進(jìn)行了二次開發(fā),搭建瀏覽器云,根據(jù)指定的瀏覽器類型,版本、以及selenium的版本等在指定的瀏覽器上運(yùn)行,滿足兼容性測試的同時(shí),保證UI測試的穩(wěn)定運(yùn)行。
接入RDC
跟集成測試一樣,通過將UI測試配入發(fā)布流程進(jìn)行卡點(diǎn);實(shí)踐中是通過RDC實(shí)驗(yàn)室的多階段將集成測試和API測試同時(shí)配到了預(yù)發(fā)環(huán)境,完成測試卡點(diǎn)。
4.6 全站式UI頁面校驗(yàn)
如上面提到的UI功能測試主要針對主流程功能性的邏輯測試,無法對頁面元素和展現(xiàn)進(jìn)行校驗(yàn),因此我們對UI進(jìn)行地毯式的校驗(yàn),采用的方法是 頁面元素+圖像比對。
基本步驟:
第一步:使用selenium對RDC的各個(gè)頁面進(jìn)行爬蟲,深度為主域名以下三級(jí)Link,并遍歷出這些頁面的元素,主要對文字、Button、Link、Form元素進(jìn)行收集,保存到數(shù)據(jù)庫中。
第二步根據(jù)前面錄制的Link,分別檢查頁面能否正確打開,并校驗(yàn)這些頁面是否包含存在的元素。
第三步爬蟲腳本完善,由于個(gè)別頁面的變化和對頁面排版的要求,對導(dǎo)致測試失敗的腳本進(jìn)行完善,去掉動(dòng)態(tài)元素,由于動(dòng)態(tài)元素不是很多在整個(gè)測試過程中影響不大;另一個(gè)是對展示要求較高的頁面加入圖像比對,提前對屏幕進(jìn)行截取(分塊截取,動(dòng)態(tài)內(nèi)容不做截取,這部分在前面的功能測試中進(jìn)行覆蓋),在回放中會(huì)對相應(yīng)頁面進(jìn)行截取,使用工具sikuli將兩個(gè)截取的圖片進(jìn)行比對。
4.7 核心接口壓測自動(dòng)化
曾經(jīng)有個(gè)故障,原因是開發(fā)的修改導(dǎo)致接口變慢。因此我們將壓測加入到常規(guī)的測試卡點(diǎn)中,在每次系統(tǒng)發(fā)布前都會(huì)進(jìn)行一次壓測,將RT值進(jìn)行對比。
(1).壓測腳本采用jmeter,在jmeter中維護(hù)系統(tǒng)的關(guān)鍵接口,將jmeter的壓測結(jié)果用csv保存,設(shè)置測試執(zhí)行的時(shí)間和并發(fā)線程數(shù),一般設(shè)置為10個(gè)并發(fā),時(shí)間為8分鐘。
(2).準(zhǔn)備基準(zhǔn)數(shù)據(jù),基準(zhǔn)數(shù)據(jù)為系統(tǒng)在穩(wěn)定情況下,將上面的腳本執(zhí)行10次,這10次執(zhí)行的rt值為基準(zhǔn)的數(shù)據(jù),并將每個(gè)接口的基準(zhǔn)數(shù)據(jù)保存在一個(gè)文件中。
(3).測試結(jié)果對比,如此每次jmeter的運(yùn)行后會(huì)產(chǎn)生一個(gè)csv的測試結(jié)果,將這些結(jié)果與之前的基準(zhǔn)數(shù)據(jù)進(jìn)行對比,如果結(jié)果落在的基準(zhǔn)期間或者未超過最大基準(zhǔn)數(shù)據(jù)10%(根據(jù)不同接口的響應(yīng)時(shí)間這個(gè)百分比不一樣),則認(rèn)為這次測試通過,并將這次通過的結(jié)果也插入到基準(zhǔn)數(shù)據(jù)中,如此不斷更新基準(zhǔn)數(shù)據(jù),最終保留30次的執(zhí)行數(shù)據(jù)。數(shù)據(jù)處理采用pyton的pandas。 如果測試不通過則發(fā)送對比圖片給相應(yīng)的開發(fā)同學(xué)。 如下圖反映了一個(gè)接口的異常響應(yīng)時(shí)間。
?? 
接入RDC
通過在預(yù)發(fā)階段新建【自定義實(shí)驗(yàn)室】 可以將jmeter的運(yùn)行腳本,結(jié)果處理以命令行的形式配置到實(shí)驗(yàn)室完成測試卡點(diǎn)。
4.8 移動(dòng)端真機(jī)測試
目前針對Android主要采用instrument的方式,對ios則采用自帶的的sdk的方式,隨之而來的問題是針對不同平臺(tái)需要兩套測試代碼。開源的macaca和appium解決了這個(gè)問題,這里選用macaca來進(jìn)行測試,相比較Appium優(yōu)點(diǎn)是運(yùn)行穩(wěn)定,去除了appium老版本Android的支持,而且macaca有專門的團(tuán)隊(duì)進(jìn)行支持。使用macaca能夠像selenium一樣對移動(dòng)端的界面進(jìn)行測試。
真機(jī)測試環(huán)境搭建
起初為了節(jié)省成本,采用了android和ios的模擬器,實(shí)踐中模擬器的可用性太差,各種啟動(dòng)慢,異常退出,基本無法使用。最終采用了jenkins+服務(wù)器+真機(jī)的集群方式,服務(wù)器安裝jekins的slave,ios和android環(huán)境,手機(jī)接入服務(wù)器,并在服務(wù)器上安裝macaca服務(wù)。
測試執(zhí)行
如上采用jekins中央集群的方式,通過jenkins來配置要進(jìn)行測試的機(jī)型,jenkins根據(jù)機(jī)型查找手機(jī)所在的服務(wù)器和手機(jī)的uid,并將測試代碼下載到該服務(wù)器,執(zhí)行測試腳本,并返回結(jié)果。
接入RDC
目前RDC尚未提供真機(jī)環(huán)境,因此我們使用Jenkins管理真機(jī)環(huán)境,然后通過調(diào)用Jenkins的Rest接口,觸發(fā)測試在真機(jī)環(huán)境上運(yùn)行,執(zhí)行完成后解析Jenkins的報(bào)告為RDC格式的結(jié)果,即可在RDC的實(shí)驗(yàn)室中展示測試結(jié)果,進(jìn)而實(shí)現(xiàn)對發(fā)布流程的卡點(diǎn)。
4.9 AOP錄制回放進(jìn)行API測試
傳統(tǒng)的API測試,一個(gè)接口一個(gè)接口的編寫代碼,準(zhǔn)備測試數(shù)據(jù),添加驗(yàn)證點(diǎn),工作量大,覆蓋不全,測試效果不明顯。這里我們引流生產(chǎn)環(huán)境的流量來進(jìn)行API測試,原理是AOP的方法攔截。主要有三個(gè)步驟,線上流量復(fù)制,回放,寫操作的Mock。
錄制回放
錄制:使用ASM修改被測接口的字節(jié)碼,侵入生產(chǎn)環(huán)境(生產(chǎn)環(huán)境提供一臺(tái)機(jī)器),在每個(gè)被測方法執(zhí)行前攔截得到需要的參數(shù),方法結(jié)束時(shí)攔截得到返回的響應(yīng)值。將錄制的返回值和方法序列化后保存到數(shù)據(jù)庫,需要注意的是對寫操作和外部系統(tǒng)的調(diào)用可能會(huì)對生產(chǎn)數(shù)據(jù)造成破壞,所以對接口內(nèi)部的方法依次進(jìn)行跟蹤,跟蹤到寫操作時(shí),錄制寫操作返回的數(shù)據(jù)。
回放:同樣采用ASM在測試環(huán)境(Beta環(huán)境)修改被測接口的字節(jié)碼,觸發(fā)接口的調(diào)用,在被測接口中使用上面錄制的參數(shù),接口執(zhí)行完成后將錄制的結(jié)果和這次執(zhí)行的結(jié)果進(jìn)行對比,結(jié)果一致則測試通過。
Mock:對于寫操作,由于我們采用的Beta環(huán)境和生產(chǎn)環(huán)境采用同樣的數(shù)據(jù)庫和外部系統(tǒng),因此到寫操作不能真實(shí)的寫入數(shù)據(jù),需要在寫操作的方法中直接返回上面錄制的寫操作數(shù)據(jù)。
接入RDC
在上面的錄制環(huán)境和生產(chǎn)環(huán)境中,安裝agent開啟http服務(wù),跟RDC實(shí)驗(yàn)室進(jìn)行通信并控制測試的執(zhí)行,最后的返回結(jié)果被RDC解析,從而實(shí)現(xiàn)發(fā)布卡點(diǎn)的功能。目前該系統(tǒng)正在改造,改造后將對云上用戶開放。
4.10 測試報(bào)告
測試報(bào)告同樣采用了分層的報(bào)告,分為:實(shí)時(shí)報(bào)告,單次執(zhí)行報(bào)告,統(tǒng)計(jì)分析報(bào)告。
實(shí)時(shí)報(bào)告
主要針對線上用例的冒煙測試,原因是測試用例全部跑完需要一定的時(shí)間,而對于線上我們希望能盡快的將錯(cuò)誤反饋給開發(fā)并解決,所以一旦有錯(cuò)誤就會(huì)實(shí)時(shí)將錯(cuò)誤信息和的現(xiàn)場通過釘釘發(fā)到開發(fā)群。
單次執(zhí)行報(bào)告和后臺(tái)日志
單次的執(zhí)行主要是對這次運(yùn)行的結(jié)果做展示,包括測試用例,測試步驟,截屏等。 在發(fā)送報(bào)告的同時(shí)我們會(huì)拉取測試時(shí)間段應(yīng)用的后臺(tái)日志,這些日志包括了錯(cuò)誤所在的機(jī)器,出現(xiàn)的時(shí)間點(diǎn),stack以及,各個(gè)應(yīng)用接口間的數(shù)據(jù)傳遞,通過這些日志能方便開發(fā)同學(xué)快速定位問題。
統(tǒng)計(jì)分析報(bào)告
在測試過程中同樣需要對測試代碼的改進(jìn)和測試穩(wěn)定性的提高,每次測試完成后我們會(huì)將這次測試的結(jié)果解析發(fā)送到我們的一個(gè)測試報(bào)告系統(tǒng)中, 對通過率,失敗次數(shù)等進(jìn)行統(tǒng)計(jì)分析,通過一個(gè)時(shí)期的分析來找出值得改進(jìn)的測試用例或系統(tǒng)功能,從而提高測試穩(wěn)定性和系統(tǒng)穩(wěn)定性。
下圖是幾種測試報(bào)告的一個(gè)圖片合集:
?? 
5 線上質(zhì)量監(jiān)控
5.1機(jī)器和業(yè)務(wù)監(jiān)控
對于機(jī)器監(jiān)控有很多開源的方案,在此不再詳訴,一般來說主要采集機(jī)器的CPU,內(nèi)存,TPS,JVM等指標(biāo),一旦某個(gè)指標(biāo)跨過紅線,及時(shí)做出報(bào)警。
對于業(yè)務(wù)數(shù)據(jù)比較復(fù)雜,根據(jù)RDC的業(yè)務(wù)有幾十種不同的監(jiān)控指標(biāo),這里我們主要采用的是日志打點(diǎn)的方式,RDC的各個(gè)子系統(tǒng)的都對輸出日志進(jìn)行了改造,生產(chǎn)環(huán)境的每臺(tái)機(jī)器會(huì)有一個(gè)專門解析日志的agent,這些agent增量的實(shí)時(shí)監(jiān)控業(yè)務(wù)日志,并將日志解析得到跟業(yè)務(wù)相關(guān)的數(shù)據(jù),發(fā)送給監(jiān)控系統(tǒng),從而監(jiān)控系統(tǒng)能得到某個(gè)點(diǎn)或者某個(gè)時(shí)間段內(nèi)的業(yè)務(wù)情況,根據(jù)劃定的業(yè)務(wù)指標(biāo)紅線給出報(bào)警。 該系統(tǒng)目前正在進(jìn)行改造,之后將提供給云上用戶使用。
5.2線上日志聚合分析
由于現(xiàn)在系統(tǒng)都采用微服務(wù)的方式,系統(tǒng)拆分較細(xì),每個(gè)微服務(wù)又都采用集群的方式運(yùn)行,因此系統(tǒng)只要正常運(yùn)行,后臺(tái)發(fā)生了多少錯(cuò)誤幾乎沒有人關(guān)心,而這些錯(cuò)誤有可能是導(dǎo)致故障的潛在隱患。
我們采用了阿里云的sls日志收集功能,將RDC相關(guān)應(yīng)用的日志接入到sls,每天晚上00:00按應(yīng)用對RDC當(dāng)天產(chǎn)生的日志進(jìn)行聚合分析,目前通過一定的算法對錯(cuò)誤信息進(jìn)行聚合,發(fā)現(xiàn)問題和缺陷,自動(dòng)提交bug,并發(fā)送當(dāng)天的統(tǒng)計(jì)報(bào)告。 目前通過日志的聚合分析,RDC修復(fù)了大量穩(wěn)定性方面的錯(cuò)誤,錯(cuò)誤數(shù)由之前每天的十萬量級(jí)降低到現(xiàn)在的千級(jí)。
5.3 SLA服務(wù)數(shù)據(jù)驅(qū)動(dòng)質(zhì)量
將用戶體驗(yàn)量化,如何為用戶提供極致體驗(yàn),一直是我們努力的目標(biāo),然后由于RDC上下游系統(tǒng)較多,如何評(píng)價(jià)現(xiàn)有系統(tǒng),采用將服務(wù)體驗(yàn)數(shù)字化,通過將每一層的服務(wù)數(shù)字化來找到問題的瓶頸。
數(shù)據(jù)的收集采用了兩種方式,一種是直接從數(shù)據(jù)庫中提取數(shù)據(jù),另一種是通過打點(diǎn)的數(shù)據(jù)提取業(yè)務(wù)數(shù)據(jù)。將這兩種數(shù)據(jù)經(jīng)過計(jì)算統(tǒng)計(jì)報(bào)表的形式展現(xiàn),從而清晰的知道目前系統(tǒng)的情況。
如圖是某一周的業(yè)務(wù)數(shù)據(jù):
?? 
通過這些數(shù)據(jù)能夠了解到整個(gè)系統(tǒng)的瓶頸,從全局了解系統(tǒng)和用戶感知的差距,并指定目標(biāo)和改進(jìn)計(jì)劃。 目前的問題是無法智能的拿到這些失敗或錯(cuò)誤的原因,比如出版本失敗率0.14%,這0.14%是什么原因?qū)е碌男枰ê艽蟮木ε挪?,如何智能的找到問題,減少排查工作是下一步要做的工作。
5.4 面向業(yè)務(wù)的穩(wěn)定性監(jiān)控和故障演練平臺(tái)
功能監(jiān)控,將RDC相關(guān)系統(tǒng)的冒煙用例在線上7*24小時(shí)連續(xù)不斷運(yùn)行,來及時(shí)發(fā)現(xiàn)線上的問題,盡量在先于用戶發(fā)現(xiàn)問題避免故障面的擴(kuò)大。
頁面監(jiān)控,同樣對RDC的頁面7*24小時(shí)訪問,看這些頁面是否能夠正常訪問,鏈接是否被修改。
故障演練,根據(jù)RDC系統(tǒng)和業(yè)務(wù)邏輯制定專門的故障演練方案,將這些演練場景驗(yàn)證點(diǎn)用自動(dòng)化實(shí)現(xiàn)并接入到故障演練平臺(tái)。目的是能實(shí)現(xiàn)可靠地自動(dòng)化故障演練,從而讓演練按需隨時(shí)進(jìn)行,發(fā)現(xiàn)復(fù)雜場景下潛在的故障。
6 .研發(fā)質(zhì)量規(guī)范和提升
研發(fā)質(zhì)量的提升目前主要包括代碼審核、代碼質(zhì)量檢查好研發(fā)效能數(shù)據(jù)的回溯。
代碼審核:在RDC上創(chuàng)建變更時(shí)會(huì)指定響應(yīng)的代碼審核人員,發(fā)布時(shí)指定的開發(fā)同學(xué)會(huì)對發(fā)布的代碼進(jìn)行審核,除了保障質(zhì)量外,最重要的是通過審核提供開發(fā)人員的代碼質(zhì)量和代碼規(guī)范,減少較低級(jí)的錯(cuò)誤。
代碼掃描:我們Sonar掃描+阿里巴巴集團(tuán)規(guī)約掃描的方式,要求對Blocker和Critical的問題必須修復(fù)后才能上線,其它級(jí)別的缺陷不能超過20%。
研發(fā)效能回溯:RDC提供的度量功能是一個(gè)團(tuán)隊(duì)的研發(fā)情況看板,它能夠反映研發(fā)團(tuán)隊(duì)在處理需求,缺陷、發(fā)布、回滾以及有效代碼量等方面的情況,從多維度的統(tǒng)計(jì)一個(gè)團(tuán)隊(duì)的研發(fā)能力和研發(fā)效率。通過每周回溯這些數(shù)據(jù),找出團(tuán)隊(duì)存在的問題,促進(jìn)研發(fā)效能的提高。
7. 總結(jié)和展望
對于自動(dòng)化測試,希望能用更有效的發(fā)現(xiàn)問題,尤其在UI測試上,考慮如何用最低的成本獲得最大的回報(bào),進(jìn)一步完善爬蟲式測試回放的工具,增加測試的覆蓋率。
線上質(zhì)量的監(jiān)控,希望能夠?qū)收线M(jìn)行預(yù)測,目前我們做到的還是對故障的處理,比如故障發(fā)生10s內(nèi)發(fā)現(xiàn),3分鐘能響應(yīng)處理完成,但是如果能夠?qū)收线M(jìn)行預(yù)測將極大的降低系統(tǒng)風(fēng)險(xiǎn),所以下一步工作是對海量錯(cuò)誤日志,故障數(shù)據(jù),用戶反饋數(shù)據(jù),監(jiān)控?cái)?shù)據(jù)進(jìn)行數(shù)據(jù)挖掘分析,并結(jié)合實(shí)時(shí)監(jiān)控建立自學(xué)習(xí)的預(yù)警系統(tǒng)。
【本文為51CTO專欄作者“阿里巴巴官方技術(shù)”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】















 
 
 









 
 
 
 