基於接口數據變異的App健壯性測試實踐

本文整理自美團技術沙龍第77期《美團億級流量系統的質量風險防控和穩定性治理實踐》,主要介紹了對網絡返回數據進行變異的客戶端健壯性測試實踐經驗。文章第一部分介紹客戶端健壯性測試的基本概念;第二部分分享了基於接口返回數據變異的App健壯性測試方案設計的思路;第三部分主要解讀了變異數據的構造和異常檢測方案設計;第四部分介紹了精簡變異數據的探索方案。

01 什麼是客戶端健壯性

在維基百科的定義中,健壯性(Robustness)是指一個計算機系統在執行過程中處理錯誤,以及算法在遭遇輸入、運算等異常時繼續正常運行的能力。IEEE中將健壯性定義爲系統或組件在存在無效輸入或壓力環境條件下可以正常運行的程度。早在1989年,Barton Miller首次提出了模糊測試的概念,通過向目標應用拋出隨機字符串的方式來測試UNIX應用程序的健壯性;而在1996年的Ballista項目中,研究人員探索根據API定義的數據類型,對操作系統或軟件接口進行自動化測試方法。兩個項目均以“無應用程序崩潰或掛起”作爲測試驗證通過的標準。

在移動端App領域,健壯性可以理解爲App運行時遭遇環境異常或者輸入異常時客戶端能夠繼續正常運行的能力。

其中,環境異常主要分爲操作系統異常、外部環境異常、硬件環境異常三大類。比如內存不足、CPU負載過高、線程池滿載、內存分配失敗、網絡連接失敗等。輸入異常主要分爲系統輸入和用戶輸入。比如網絡接口返回的數據異常、應用內緩存、數據庫文件讀寫異常,這類的異常屬於在系統輸入異常;在電話號碼輸入框場景,用戶輸入的空格、富文本則屬於用戶輸入異常。

對於這些風險,如果App沒有處理,理論上都可能會產生展示異常、交互異常、性能、安全等問題,導致用戶無法繼續使用或在使用過程中產生不好的體驗。比如用戶操作App下單過程中,API請求出現故障未返回狀態碼爲200的響應,App由於沒有獲取到預期接口響應的信息而發生崩潰,就會中斷用戶的使用流程。

02 基於接口數據變異的App健壯性測試方案設計

在實際的客戶端測試執行過程中,測試人員會考慮測試異常輸入的場景,但由於成本無法做到無窮盡的測試,同時還存在人工執行遺漏的風險。

從美團App平臺業務的歷史故障分析中,我們發現:網絡請求返回的數據與實現預期不符引發的Crash或核心功能缺失問題導致的故障佔比最高,且影響面較廣。比如接口返回非預期數據時,客戶端處理數據類型轉換異常導致閃退,即使5分鐘內操作降級仍影響了百萬量級的用戶。因此美團平臺業務App的健壯性測試探索優先從發現網絡請求返回數據導致的異常開始。

針對於發現請求接口返回客戶端非預期數據導致的Crash,或者核心模塊缺失問題這個訴求,我們調研後發現方案的基本原理都是相似的,即以網絡請求的原始響應爲基礎,根據規則進行變異構造,使用代理工具改寫響應體返回給客戶端,在端上設備做異常檢測。但是都存在一些問題不能滿足訴求,比如測試變異數據是根據預置或者自定義規則隨機生成組合,隨機性過大,不能有效攔截健壯性問題;但如果不做隨機,產生的用例組合量過大,測試不能在合理時間範圍內結束;另外在檢測能力方面,不具備發現業務異常或功能模塊異常的能力。

因此,我們結合通用方案做了一些自定義改造,整體檢測方案包含靜態檢測和動態檢測兩部分。

  • 靜態檢測,主要是指靜態代碼掃描,將典型代碼編寫規範問題轉化爲自定義靜態代碼掃描規則,管控增量代碼,同時長期治理存量風險。比如自定義了PrimitiveParseDetector、ColorParseDetector,管控業務必須使用健壯性測試通過的工具類。

  • 動態檢測是指結合觸發時機,構造並注入變異數據後,識別App運行時是否出現崩潰、掛起或業務功能模塊異常。比如在集成事件/迴歸事件觸發自動化測試運行,構造觸發異常的數據進行動態測試,然後監測是否出現了異常。核心動作包含構造變異數據和完成檢測兩部分。比如將接口響應體中表示顏色含義的Key對應的Value值構造成非色值,然後檢測客戶端請求處理接口數據時是否出現崩潰或掛起。

下文重點介紹端到端的動態檢測方案。

03 變異數據的構造和異常檢測

對於美團App來說,首頁有多種形態,對於某種特定形態,除了控制請求數據外還需要控制實驗、策略等一系列因素,才能保證測試對象的唯一性。一個頁面中包含多個異步請求,因此請求的構造也需要和頁面路徑關聯。這些都是採集變異所需的基礎數據時需要關注和控制的。

響應體由基本類型數據和複合類型數據組成,相同基本類型的數據可能具備不同的業務語義,需要根據語義的類型做變異規則的區分對待,才能保障業務場景覆蓋。

因此,如何保障變異數據構造的全面性和準確性,是我們面臨的首要挑戰。

要解決數據構造全面性問題,首先要解決頁面描述方案,這樣才能控制獲取基礎數據的唯一性。在解決方案中,我們構建了頁面描述的特徵規則,解決用戶視角的頁面標識問題。需要的信息包含端信息、頁面路由信息、實驗策略賬號信息、頁面標識模塊合集等。通過頁面請求數據自動錄製的方式,自動更新迭代請求數據和頁面之間的綁定關係,使得基礎數據能夠隨需求迭代更新,從而通過變異規則構造生成的用例也能夠自動更新。

在用例變異生成構造上,對於響應體裏的Value設置了語義匹配規則,比如字符串的語義可能代表顏色、頁面跳轉路由、動靜態資源鏈接(即圖片資源數據/視頻文件/GIF文件),需要區分特徵分別按語義構造異常數據。比如在圖片的變異數據構造裏,除了需要構造非圖片鏈接情況外,還要考慮不同圖片格式、非圖片格式以及非合法的圖片剪裁格式拼接等場景。

我們對接口返回數據使用腳本做了初步的語義分析,人工二次校正後建立了基本數據類型和語義的映射集合,結合基本數據類型邊界值和語義定義了初始的變異規則。然後對歷史的線上健壯性問題和線下測試發現的健壯性Bug的變異數據進行整理,作爲增補的變異規則。

在自動化測試執行過程中,我們基於App可測性改造提供的能力,對測試場景進行了控制,同時基於佈局視圖的解析SDK、App異常上報SDK提供的能力,完成了對App異常的通用檢測。

04 變異數據的精簡方案

伴隨着變異規則的豐富,自動生成的數據量級是巨大的,數據的變異組合如果按照全覆蓋方式來生成組合數量就是指數級增長。比如對於1種有7種變異取值的變量,如果存在n個此類型變量,就會產生7^n種數據組合,並且在實際業務場景中很多組合情況是沒有意義的。

如何在保障用例構造全面性的情況下精簡變異構造的用例數,是我們面臨的第二個挑戰。解決方案包含2個策略:1)數組元素結構一致時,刪減構造的用例數;2)結構不完全一致的數組元素,引入編輯距離和並查集算法判斷節點相似性,節點不相似,可以在一次數據生成裏做合併構造。

我們可以把請求響應的JSON理解成樹,第一個解決思路是判斷樹中節點、路徑的相似度,相似節點刪減構造。

如果路徑、節點相似,可以推測路徑即業務邏輯也是一致的,比如頁面上的一些列表元素,可能是數據結構對象完全一致數組,如果對每個數組對象中的每個元素進行全用例構造,生成的變異數據量極大,且對業務場景或代碼邏輯的增量覆蓋有限,因此我們決定將構造邏輯優化,進行刪減構造。即假如數組中元素的結構完全一致,那麼同含義的字段可以爲他們分配不同的變異構造值,然後刪減掉無效的構造情況。應用這種方法可以有效降低28%左右的用例構造數量。

如圖數組的3個元素中均存在“resourceName”鍵值對,假如每個鍵值對有3種變異取值,按照全排列方式進行用例構造將會生成有9份變異數據,在刪減構造情況下,可以分別爲它們構造一個特定的變異值,這樣變異生成用例數量可以從9減少爲1。

在對業務接口返回數據的數據結構進行分析後,我們發現在層級越深的場景下,距離根節點越近的兩個節點,業務邏輯耦合和結構相似程度越低,它可以進行合併構造,相互邏輯之間不會產生影響,比如有兩個鍵值對,每個鍵值對的Value有3種變異取值,在合併構造情況下,可以從排列組合的6份數據減少到3份數據。

基於這個個思路,我們在實踐中引入了編輯距離和並查集算法,以節點路徑爲參照,對樹的每一層的每兩個節點計算編輯距離,生成一個n*n矩陣;同時以樹的高度減去節點位於的層數作爲權重,修正編輯距離。基於這樣的計算,會產生多個編輯距離矩陣。

爲了嘗試最大化合並構造用例效果,我們把編輯距離做了0,1矩陣轉化。其中,由於編輯距離爲1的兩個節點可能存在業務邏輯耦合關係,必須放在同一個組裏分別構造,所以我們把編輯距離大於1的情況轉化成了0,最後得到了一個0,1的編輯距離矩陣。

在0,1矩陣情況下,我們使用了圖的連通性概念,如果A和B連通,B和C連通,那我們認爲A和C連通,轉化到這裏的概念就是A和B相似,B和C相似,那麼A和C相似,它們應該被放在同一個組裏分開進行構造,那麼在同層元素構造時,我們會從每個分組裏取到一個節點,對這些規則進行變異組合構造。

基於以上兩個策略進行精簡後生成的變異數據量較精簡前降低了40%,同時代碼覆蓋率沒有明顯變化,並且保持不變的健壯性問題發現能力。

美團App和優選App都接入了這個工具,在新需求階段可以人工觸發運行,還可以結合客戶端組件集成事件和迴歸事件做自動觸發。至今應用一年時間內,發現了幾十個問題。

05 總結及展望

在健壯性工具建設一期裏,我們實現了App頁面加載展示場景的健壯性問題檢測,支持崩潰、卡死和部分功能異常這三類異常檢測。另外,基於節點相似性優化變異數據生成策略能夠在保持效果不變的情況下有效控制測試時長,但是否有更優的合併算法和推薦算法,還需要更多的嘗試。

在後續工具的迭代還會繼續圍繞異常構造和異常檢測這兩個方向,支持更豐富的構造能力和檢測能力,以及更高效的構造效率。短期建設上,我們將會從業務視角出發豐富自動化變異數據生成建模,完善客戶端異常通用異常檢測能力,完成通用前後端交互的數據構造類型(比如:長連接消息)的覆蓋;長期建設上,需要支持更豐富的數據和環境構造能力,通過智能化用例生成,提升測試效率。

06 Q&A

Q1:節點相似的判斷依據是什麼?

A:從實際的response分析來說,兩個節點的路徑完全相似就是從根節點到最終的葉子節點上,它們的路徑命名完全相似,數組裏兩個對象的結構完全一樣。

Q2:用例的生成能舉個例子嗎?

A:比如顏色色值的格式是#+6位字符,通常運營配置會出現的情況是忘記添加#,或色值複製中少了一位。在這種情況下,我們會構造一個色值,比如沒有返回#、色值位數不對、色值添加透明度,把這種場景作爲構造情況,在配置裏添加上,最後用代碼生成。

Q3:健壯性平時執行的頻率是什麼樣的?

A:第一個基於需求維度,需求維度需要人工觸發;第二個基於變更維度,當組件發生變更時,可以關聯到這段代碼或者組件變更的頁面,然後觸發頁面對應的健壯性測試,執行頻率會受到組件變更頻率的影響;第三個在迴歸測試時,App的迴歸測試兩週一次,我們會把所有頁面以及它關聯的所有的用例都執行一次。

Q4:對於暴露給前端開發的接口,大部分是人爲調用參數的變化,隨機性相對比較高,對於必填和非必填參數如何確認用例的範圍?

A:目前我們在實現的方案裏,沒有區分參數是必填參數還是非必填參數,所以對於整個數據接口返回裏的所有結果都會進行構造,產生的問題是對於非必返回的參數可能產生的問題,到底是否是需要解決的問題,這部分目前通過運營手段做確認。

Q5:首頁可能調用10個接口,然後針對每個字段都進行異常驗證嗎?

A:對於首頁關聯的接口,我們在接口請求、錄製過程中和錄製完數據後,會對接口進行確認到底有哪些接口是我們需要驗證的,這是一次性的成本,錄製完成後,會對每個字段都進行異常驗證,當然會有一些黑白名單的設置。

Q6:對色號這種情況有一種生成規則嘛,這個規則是怎麼制定?

A:剛剛我只是舉了一個色號的例子,其實對於圖片、請求的資源文件、配置文件、跳轉鏈接,每一個對應到的業務語義,我們都有對應的用例生成規則,我們會根據參考依據,比如第一個是本身我們在通用的基礎庫裏怎麼處理這些問題,這裏有一個基礎的規則;第二個是我們積累了線上問題情況實際可能會產生的錯誤或者變異情況,生成第一版基礎規則,在第一期工具裏找相關研發達成共識,這樣的話,數據變異是處於合理範圍。

Q7:執行的時候,如何知道頁面對應哪些規則提前配置?

A:執行時,在測試接入過程中有一個配置過程,它不是配置這個頁面和接口的關聯關係,而是配置我們要測試哪些頁面,自動觸發自動化錄製過程,就是到這個頁面時,會觸發哪些接口請求,生成這個頁面和這個接口請求的對應關係,給到對應的配置人做確認,保證哪些接口是真正可能想要構造的,哪些接口不需要構造,最後以這個爲基準測試,基於錄製過程,比如業務迭代裏面產生了新接口,我們在錄製中能夠感知到它關聯的接口發生了變化,在發生變化時發消息給對應的測試提交人/負責人,TA確認這條規則放到黑名單裏還是更新到需要構造的接口裏。

Q8:是否有做頁面顯示的一個校驗?怎麼做的?

A:目前我們在頁面裏的模塊做了“是否展示”校驗,基於當前集成到美團的可測性SDK,這個SDK會獲取到當前頁面是否渲染裏是否展示了對應模塊的信息,通過請求把對應模塊描述傳給SDK,通過返回來校驗是否展示。

07 參考資料

| 在美團公衆號菜單欄對話框回覆【2023年貨】、【2022年貨】、【2021年貨】、【2020年貨】、【2019年貨】、【2018年貨】、【2017年貨】等關鍵詞,可查看美團技術團隊歷年技術文章合集。

| 本文系美團技術團隊出品,著作權歸屬美團。歡迎出於分享和交流等非商業目的轉載或使用本文內容,敬請註明“內容轉載自美團技術團隊”。本文未經許可,不得進行商業性轉載或者使用。任何商用行爲,請發送郵件至[email protected]申請授權。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章