【NCTS峰會回顧】搜狗科技王鵬:如何通過精準測試來解決效率黑洞
2019年10月26日,由Testin主辦的第二屆NCTS中國云測試行業峰會在京召開,此次峰會以“AI+未來”為主題,匯聚來自國內外測試領域的知名專家學者、領先企業決策者、高層技術管理者、媒體從業者等,共同探討高端云測試技術,幫助測試從業者了解最前沿行業趨勢,及最新的行業實踐。
搜狗科技資深高級測試開發工程師王鵬做《如何通過精準測試來解決效率黑洞》主題演講。王鵬指出,“精準和智能是精準化測試聚焦的兩個點,而如何從經驗型方法中提升技術性的手段則是精準化測試的目的。”
以下為王鵬演講實錄:
大家好,今天我給大家分享的主題是《如何通過精準測試來解決效率黑洞》,我希望大家聽完后,可以想想現在適不適合開展精準測試,如果現階段不適合,我的目的也達到了。第二點,如果確實可以做精準化測試,我希望大家聽了以后學到一些方法,能知道哪些階段引入哪些方法可以解決哪些問題,達到什么效果,想做的話,回去后,可以開始一步步開展。
分享分三個部分:1、影響我們測試效率的因素有哪些,既然做這件事肯定是事出有因的。2、簡單介紹一下精準化測試思想。最近精準化測試起來了,有的同學對此了解不是很深。3、介紹一下我們提升效率的具體方法有哪些,每個階段都會詳細給大家介紹。
首先說一下影響效率的因素,這是和大家訴苦了。我這個題目選了“黑洞”這個詞,大家看這張照片是前一陣NASA發現的第一張黑洞照片,選這個題目的時候,這張照片還沒有呢,為什么選黑洞,效率為什么是黑洞,因為他們有類似的地方,黑洞是什么?質量特別大但是體積很小,我們平時工作是什么樣的?測試的工作非常苦,付出非常多,但有可能成效非常少。是什么造成了這樣一個情況?
分析了一下:
1、投入產出比。不知道大家平時做事的時候有沒有考慮過這個事情,這個事情其實對你自己的影響非常大,大家可以好好想一想,經常有人說我們工作效率低,這直接對我們個人的影響就是你的創新性工作啟動特別難。作為一個測試工程師,如果我正天被我的工作羈絆,成天做重復的工作,也許很多人都是這樣,最開始我也是這樣,那么就很難開展一些創新性的工作,或者你和老板提出有一些想法要做這些創新工作,也可能沒有時間,老板會跟你討論,這些創新工作投入產出比怎么樣、收效怎么樣、付出這么多時間下面如何?這是我們面臨的困境。
2、我們的成效不可衡量。這個很多分享嘉賓提到了,不出事還好,一旦線上發現什么問題,往往追溯的時候,開發可以查代碼,我們整個測試過程怎么回放,不可衡量,我昨天這么點的沒有出現問題,今天還是這么做出現問題了,你說我到底錯在哪兒?我們的工作不可衡量的話,真正較真計較這個事情的時候,我們就處于非常非常被動的地步。
正因為這兩部分,這次出事了,下次投入更大的精力去做,從另一個角度講就是影響你的效率。
說完我自己的切身體會再來回顧一下我們平時的工作,我列了兩項:黑盒測試,白盒測試。大家可能覺得老生常談,其實不是這樣的,黑盒測試我們今天聽分享有好多高大上的方法,據我們了解,在很多大廠包括很多公司里,黑盒測試的同學仍然占80%以上,這是不可規避的一個問題,大量的同事還在從事著黑盒測試工作,那么我們怎么幫助他們其實是一個非常重要的問題。
說到黑盒測試,準備從三個方面說一下,過程、效果、管理。黑盒測試的過程是怎樣的?因為黑盒測試是看不到代碼的,在整個測試過程中伴隨著很多猜測的成分,在測這個功能的時候可能憑借你的經驗猜,它可不可能出現一些問題,設計測試用例的時候也是靠猜的。第二不穩定,體現在很多方面,極端的例子,今天測的和昨天測的可能就不一樣,今天身體不舒服測的版本效果可能跟身體好的時候也不一樣。第三難控制。正因為這么多因素造成整個黑盒測試的過程是不可控的,我說測一個90分的版本來,怎么確定這件事情?
效果跟個人素質關系很大,一個新人和一個有經驗的老人對業務測試的質量,這個區別是很大的,在座很多管理者,如果你管理的是一個黑盒測試團隊的話,你面臨的難度是什么?要管理測試開發團隊評估你的代碼開發能力、代碼設計能力,其實不是一個很難的事情,咱們打幾次交道,你給我實現幾個功能就基本知道你的底了,就知道什么樣的工作可以交給你開發,業務怎么辦?你可能有自己熟悉的業務,比如說來了一個測試需求,測試需求里的很多業務,30%是你熟悉的,70%是不熟悉的,能不能交給你,如何選擇一個合適的同事測這個版本?這是一個非常大的問題,是對黑盒測試團隊管理者提出的很大的挑戰,出現問題時我們反思,測試過程中這個問題需要注意、那個問題需要注意,管理者有沒有捫心自問為什么選擇他做這件事情,如果選擇另一位同學能不能規避他犯的錯誤?這是很難的事情。
另外聊一聊白盒測試,在座有做白盒測試的嗎?有兩個,不知道你們是不是互聯網行業的,其實我是不建議在互聯網行業做白盒測試的,因為白盒測試產生是以前像微軟Office這種開發周期極長用白盒測試,互聯網一天上線三個版本,做完以后門檻高,團隊里有一到兩個人能做白盒測試嗎?單兵作戰,你測一半能不能交給另外一個同學?沒法交接只能自己做。第三目標比較單一,做白盒測試的時候一般評價我們測試是否到位,基本只能依靠覆蓋率,白盒測試過程中覆蓋率達到一定指標了就說明OK,目標非常單一。還有沒法大家一起做,一個版本來了大家一起做白盒測試,最后把結果匯總到一起,這個也是很難做的;第四就是分析之殤投入產出比比較低,有可能做完以后只能告訴“看了,這些邏輯確實都覆蓋到了,沒有問題”但是你發現bug了嗎?一個也沒有發現,這種情況很常見,所以白盒測試對于互聯網行業是不合適的,所以現在其實很早大家就在做灰盒測試了。我們基本上測試是通過黑盒測試做的,在黑盒測試基礎上更高效的解決問題。這是我們面臨的現狀。
第二,就給大家介紹一下精準化測試思想,簡單介紹一下,這有一句話我念一遍,因為我看過很多精準化相關的資料,我認為這句話總結的非常到位,精準化測試就是“用非常精準和智能的軟件來解決軟件測試的問題,并從根本上引領軟件測試,從經驗型方法向技術性方法的轉型”。它強調兩點,首先當然是需要解決問題的,精準和智能是精準化測試里要聚焦的兩個點,如果做精準化測試一定要聚焦在這兩個點上,它要達到的目標是什么?從經驗型方法向技術性方法轉移,黑盒測試大多依賴于經驗型方法,如何在經驗型方法中提升技術性的手段就是我們精準化測試的目的。
分別介紹一下,首先介紹一下精準要做哪些事,我們這邊的精準1、測試用例到代碼邏輯精準記錄的雙向追溯。什么叫雙向追溯,執行黑盒測試用例直接就能映射到你的代碼邏輯上,看代碼邏輯也能反向用到測試用例上,一定是雙向的,如果是單向的,這個效率是提高不了多少的。怎么實現?代碼邏輯到測試用例是通過函數調用關系計算來的,我們提出一種方法叫代碼染色,這兩個都會在后面詳細給大家介紹。
2、精準的代碼級的缺陷定位和崩潰分析。在做黑盒測試的過程中,我們一定要給黑盒測試同學提供什么樣的方法?測著測著發現一個bug,他自己就知道哪塊代碼出問題了,要達到這種效果,崩潰也是要能落到崩潰分析上。
3、精準的測試充分度分析,主要是解決測試不可度量的問題。
智能有哪些?主要列了3點:1、回歸用例的自動篩選;2、自動化用例篩選與執行;3、持續集成。
第二部分就簡單介紹到這,主要介紹第三部分,告訴大家如何去做,上面那些事,如果我想做的話一步步怎么做?我給大家分享我們在搜狗社區具體應用的案例,我們現在正在做的事,大概是做成什么樣子。
首先再給大家提一下影響效率的因素,因為我們這里主要要解決效率的問題,列了很多,剛才也有人說過了,1、團隊新人沒有經驗;2、團隊新人能力不足;3、測試范圍圈定憑經驗。這里我們經常遇到那種情況,開發改了一段代碼,需求上寫的很清晰,我們都測到了,但是卻有另外一個場景出現問題,是有關聯的,我們很難把那部分測試用例圈出來。4、測試用例篩選難,讓你從曾經的測試用例篩選出這次的測試用例,這個很難。5、測試經驗沉淀效果差,我們這個測試經驗沉淀基本是口口相傳,沉淀的東西是靜態的,無法動起來,看代碼、整理接口、就編成一篇篇測試文檔,或者在某個軟件、某個平臺里落在那兒了,它動不起來,不實際,用到不會查,查還可能查不全,怎么讓這些資料主動為你提供幫助,這是我們做的事情。6、測試人員狀態不穩定,主要是指大家的心理和生理狀態。
最初我們給自己提了4個目標,我們要解決的問題:1、要精準圈定我的測試范圍;2、對影響的范圍必須給出建議;如果測這個版本要有個東西,暫且叫它軟件,要告訴我還有哪些東西要考慮。3、自動篩選測試用例,要測這個版本了,至少給我一份測試用例讓我做參考。4、為黑盒測試提供實時覆蓋率結果。
為什么強調實時覆蓋率改革呢?有時候我們經常做覆蓋率,一堆功能做完了,讓我們出一份覆蓋率軟件去分析,發現有幾行沒有覆蓋到,再往回推,效率也是比較低的,我們要達到什么情況?比如,我執行了非常短的業務流程可能就是一個登陸,三步操作,輸入用戶名、輸入密碼、提交,這三步操作希望知道我的覆蓋率是什么,及時調整覆蓋用例,這個對我們價值是比較大的,所以我們必須為黑盒測試的同學提供實時的覆蓋率分析。
剛才說了那么多我們一步步介紹,下面是具體每一步是怎么做的:
篩選測試用例,一共做了三步:版本提測的時候做哪些事情,首先會提供提測版本的信息和線上版本的信息,我們對這兩個版本進行diff,計算出diff結果,結合變更函數計算,通過調用函數關系的計算,現在想想diff軟件里面是有很多代碼段的,告訴你在哪一行發生了變化,這一部分是他提供給我們的信息,我們要從這個信息里得到什么結論呢?首先要把變更函數計算出來,這些代碼段映射到函數上是哪些函數發生變動這我要知道,那么和這些函數相關聯的還有哪些函數?它的調用關系我們要知道,要做到這兩點,要從diff結構解析后面兩部分。第三是測試用例生成,解析出來的函數映射到測試用例上,這些函數發生變化或者這些函數關聯的功能發生變化就可以把這部分測試用例篩選出來。
針對依賴關系舉個例子,開發為了實現功能1,同時修改了函數A和函數C,其中函數之間調用關系功能1是C調用A,功能2是B調用A,開發是改了A了,提了C這個場景,B調用A就可能出現問題,函數調用關系計算就是為了解決這樣的場景。
我們這邊服務端的語言都是JAVA,所以我們是使用了JAVACG工具,通過對class文件解析計算函數之間的調用關系。具體就是如圖這樣的結果,當你解析對于class穩健的時候會輸出這樣的文件,一大堆調用關系在上面,但是只是一層調用關系,我們需要通過這種一層調用關系把他們串起來,左右關聯一下就可以了,所以我們要把函數調用鏈關聯起來,當然你也可以看到,其中有很多第三方庫的函數調用關系,其實可以通過過濾器把不相關的過濾掉。
diff結果解析怎么做的,變更代碼段,解析diff結果文件,計算變更文件名和變更代碼段的位置信息。它會寫第三行第五行發生了一堆操作,這個代碼段我們要通過整個diff結果文件算出JAVA文件里的代碼信息解析出來要保存。變更函數怎么辦,我們通過掃描源文件和代碼段的信息判斷一個包含關系,比如函數A包含了這個代碼段我們認為函數A發生了一種變化,通過這種方式計算變更的函數分類。影響范圍怎么計算?結合函數剛才說的調用關系,圈定受影響的函數范圍,是這樣的流程。
舉個例子,比如diff結果,A.java,code有個開始位置、結束位置,A.java原文件里也有這些信息,你會問,如何判斷一個函數結束的位置,開始位置可以判斷,因為你知道可編譯的函數自己本身是有編譯器的,不用達到那個級別,比它簡化很多,只要把函數位置提取出來,肯定是有一個class特征的,函數開始位置是沒有問題的,結束位置大概理解成下一個函數開始位置的上一行,但是可能有細節,有嵌套類、其他函數的套用,這一塊細節的地方處理一下但是整體思路是這樣的。所以如果第一個代碼段落到函數1的區間范圍內的話,我們認為這個代碼段屬于那個區間,大概就是這樣的過程。
如圖就是具體解析SVN diff的結果,代碼段,大家拿到PPT可以詳細參考一下,我不詳細講了,非常簡單。三種定義方式我們如何判斷函數,只要把函數信息確定,位置信息拿到就可以了,不用做更深的分析了。
我們實際達到的效果是什么?我們要達到什么樣的效果?以我們工程為例,給出兩個版本號,這兩個版本是這次提測的版本和要比對的版本,底下就會把它的變動函數計算出來,這個變動函數就包括依賴的函數,因為這兩個選的比較近,改了這些內容,我們這次需要關注的所有范圍的函數信息就在這里。
前面主要介紹從代碼層面影響范圍,最終還是要落在測試用例上的,這是最關鍵的事情,那么怎么做的?其實我們也是從一些笨方法開始的,這個東西有時候不可能一下達到最優的方式,給大家介紹一下整個的歷程,大家可以思考一下。
首先,人工錄入是一種非常低效的方式,但是為什么從它開始呢?因為我們以前就做這件事,我們其實雖然不做白盒測試,但是我們也是做灰盒,測試人員也是需要看代碼的,看代碼了就讓他錄入時比較順手,這件事情不可持續只是它原本效率就很低,人工閱讀源碼梳理與業務相關的函數,并與測試用例建立相關性,看懂了這個函數,覺得和哪個用例相關的就人工手動關聯上。這種占20%,他們會提一些抱怨,我們怎么給他們提供輔助信息,工具也跟開發達成一致,因為他們也希望提高自己的代碼質量,要求他們寫良好的注釋,我們推動開發撰寫注釋,使用工具把函數和注釋信息抽出來,那里面有和測試用例對應的場景,還是需要人工建立測試用例的相關性。這一塊大概占30%,我定義叫中效,其實它的效率也不高,而且還有可能開發寫的注釋,你理解上有偏差的地方,但是比第一種又多了一些輔助信息在,其實最好的是比較高效是代碼染色的工作,根據測試人員行為自動錄入測試用例和函數的對應關系,我們特別希望做黑盒測試的時候可以錄制黑盒測試行為,這樣是最好的方法。
可以看一下最笨的方法是用excel的方式,并不是強制要求大家從零開始做這件事的,其實之前也開始做這件事了,只不過要求它和測試用例級對應上,后來我們提供了一個平臺,但是沒有從根本上解決這個問題。如圖這是做代碼覆蓋率的時候,做覆蓋率分析的時候可以直接把函數相關的內容錄入進來,效率是有提升,但是還是沒有解決最根本的問題。
給大家介紹一下代碼染色的思想,代碼染色分5步,離不開覆蓋率,首先我們在執行黑盒測試用例的時候,會收集覆蓋率,因為我們已經做到了黑盒測試覆蓋率的實時收集,比如開始錄制我的行為的話,黑盒測試執行一段行為,收集覆蓋率,解析覆蓋率的結果,覆蓋率當中發生變化的函數和這一次執行肯定是有關系的,我們會把這些代碼進行染色,染色就會和測試用例級反向對應上,再結合之前的函數調用關系的計算,相當于把范圍稍微放大一點,這些函數如果發生變化的話都會映射到黑盒測試用例上,這樣就形成了雙向追溯,執行用例也可以到函數級別,函數級別變化可以映射到用例上,這種方法效率就得到了很大的提升。
篩選測試用例的流程如圖,首先是基線版本代碼和測試版本代碼diff,對diff結果進行解析計算變更的軟件和方法,計算方法會把依賴關系入庫做比對,如果發現庫中有的話,直接會從用例庫里篩選出來,有一部分新增的需求肯定是要手動撰寫用例的,這部分沒有辦法,需要手動把用例補上,最后合并成一份完整的測試用例。
如圖這就是我們最終達到的結果,當你篩選出來結果的話,包含所有函數的信息以及對這種函數的理解和最后要執行的測試用例級,點進去可以直接執行測試用例。
簡單給大家說一下覆蓋率,我們主要做兩種,JAVA覆蓋率和JS覆蓋率,JAVA不多說,大家都用jacoco,但是我建議用on-the-fly模式。JS我們選擇了一種工具,大部分工具都是支持單元測試的,對我們黑盒測試不是很友好,我們基于JScover做了二次開發,實現插樁上報加代理的方式,同時支持源文件和ES6編譯文件的插樁。
JS多說一句,覆蓋率無非要做四件事,代碼插樁、數據上報、文件映射、生成報告。代碼插樁主要針對源文件和編譯文件,JScover就可以做這件事情。數據上報可能需要改動一些代碼,文件映射需要一個代理,把所有線上的請求映射到本地這一塊需要有個代理。生成報告這塊,實際上自己支持的也比較好。
數據上報,可以通過一些事件進行數據上報,這里列了兩個,比如頁面切換,像測PC的時候,如果頁面發生切換就讓它報上來一次就可以,無線的話可能涉及到滾動,這樣的話一般是鼠標移動,不要行行都報一次,那樣對業務測試壓力比較大,比如鼠標往下滾動一次,鼠標有操作了就報上來一次,這種不會發現前端測試有性能問題,工具引起的性能問題不會有,這個效果還不錯,這個大家感興趣可以回去看一下。
說一下ES6,為什么要兼容ES6標準呢?前段時間大家都用JS框架開發,他們都是采用ES6方式了,已經不是原生JS了,之前是在JS插樁就可以上報了,需要編譯的話像右圖這種怎么辦?選擇一個什么節點進行插樁呢?源碼是易讀不可執行的,這種插樁沒有意義,編譯后較易度可執行,壓縮混淆后不易讀,可執行,我們選擇了這種方式對編譯后的插樁,這樣可以選擇ES6的開發模式。
大家參考一下就可以了,這是我們一個覆蓋率分析的,有JS的工程也有JAVA的工程,都是支持立即收集覆蓋率的,前端做一些工作就可以覆蓋率實時察看,這是覆蓋率的基本信息,如圖相當于左邊是JAVA的結果頁面,右面是JS的,JAVA這一塊有一個bug的提示,相當于這是一個diff結果,看哪塊沒有覆蓋,如果對這一塊函數有告警說它有bug的話也可以察看,都可以打通。這是我們整個的測試流程,把它列在這兒,如果做精準化測試的話,可以在哪個部分把這個事情做了。首先提測前,跟大家差不多,需求評審、用例編寫、用例評審、提測前準備、提測走查,這個主要支持在提測到預發布、上線支持的部分,我們篩選出來的測試用例不僅用于測試人員而且還用于開發的提測前的默驗測試以及產品提測前的走查。
我們現在做的工作如圖,可能每個公司都有不一樣的東西,我們這邊不是運維發布代碼的,實際上開發有很大的權限,它可以直接把代碼發布,我們對開發所有發布系統做了監控,他們有代碼發布,無論是線上還是測試環境,我們這邊會啟動所有的操作,只要有一次發布這一塊都會自動執行,如果有測試的話在他提測行為發生以后,我們測試人員就會收到一封郵件,郵件里包含上述所有的計算結果,測試之前就可以拿到所有的信息,最大化幫助功能測試人員提高他的測試效率。持續集成這一塊也會跟很多自動化平臺打通這些自動化都是精準自動化,都是通過篩選出來的自動化用例。
以上就是我的全部分享內容。