1. 程式人生 > 其它 >阿里巴巴如何進行測試提效 | 阿里巴巴DevOps實踐指南

阿里巴巴如何進行測試提效 | 阿里巴巴DevOps實踐指南

編者按:本文源自阿里云云效團隊出品的《阿里巴巴DevOps實踐指南》,掃描上方二維碼或前往:https://developer.aliyun.com/topic/devops,下載完整版電子書,瞭解阿里十年DevOps實踐經驗。

在任何業務發展的過程中都會不可避免的面臨服務的膨脹,應用複雜度的增加,可持續測試的難度不斷增加。一方面,用例集會不斷的膨脹,一次 CI 驗證要數十分鐘,用例的維護成本越來越高,開發效率開始降低。另一方面,我們花了精力寫了很多自動化用例,希望能夠提高投入產出比,也就是測試的有效性。

提升測試速度

分散式測試

分散式測試的核心思想是通過增加計算資源,併發的對 case 進行執行,並在執行後對測試產生的結構化結果進行解析合併,進而提升單次測試的執行速度。

整個測試的執行過程可以劃分為以下三個階段:

  • 測試用例解析與分發
  • 分組用例的執行
  • 分組測試結果合併

以阿里雲某雲產品核心團隊的某工程為例,該工程擁有 1 萬多個單元測試用例,在沒有采用分散式測試方案之前,一次 CI 的驗證時長超過 4 小時,導致問題發現、修復時長拉長,影響了日常的迭代速度。該團隊後採取了分散式測試的方式進行,平均的執行時長被優化到了半小時以內。

分散式測試的本質就是用執行資源的堆疊,去換取更快的執行速度。理論上我們把每一個測試用例拆分到一個容器內執行,可以獲得極致的反饋速度。但是並不是所有場景下都適合採用分散式測試,例如用例之間存在依賴,這些用例不能無差別的分佈在不同的執行分組。

精準測試

分散式測試很大程度上解決了測試執行的速度問題。但是如果在任何情況下都無差別的執行全量的用例,會存在一些問題:

  • 對計算資源的浪費
  • 引入了大量的無效執行
  • 用例本身穩定性問題導致排查時間浪費
  • 在探索測試有效性的過程中,我們引入了精準測試的方案

什麼是精準測試?

通過建立測試用例與業務方法的關聯關係,在程式碼發生變化時,精準的推薦出需要執行的用例,進行測試執行與結果反饋。通過精準的圈定測試範圍,可以帶來效率和速度的雙重收益。

精準測試的基本要素

  • 測試用例(Case)與應用程式碼方法(CodeMethod)關聯關係的建立。這種關聯關係,我們定義為基線
  • 程式碼發生變更,根據基線中用例與應用程式碼方法的關聯關係,準確推薦出變化的方法、關聯的測試用例
    變化的測試用例,並進行執行。

如何建立測試基線

  • 基線的建立方式有多種,在阿里巴巴內部使用過以下兩種方法去建立用例與程式碼的關聯。
  • 通過位元組碼注入的方式,埋入 trace 呼叫,並在呼叫中傳入用例與業務方法的簽名。通過採集 trace 的日誌,拿到所有的測試用例與方法呼叫鏈路,建立起用例與方法的關聯關係。
  • 通過 AST 解析的方式。

如何進行用例推薦

在程式碼發生變更後,會基於程式碼變更解析出變化的測試用例與變化的業務方法。方法的變化通常是新增、刪除、更新。

用例的程式碼變更情況比較簡單,所有新增和更新的用例都會納入到迴歸範圍。

被測應用程式碼變更,要分情況考慮:

  • 新增的方法:匹配不到任何用例,針對此次變更,開發或測試可能補充了測試用例,也可能未補充,需要進行提示。
  • 更新的方法:更新的方法分兩種情況,第一種,更新的方法有關聯的用例,需要推薦出來;第二種,更新的方法原本就沒有關聯任何用例,需要提示使用者補充測試用例進行覆蓋。
  • 刪除的方法:刪除的方法也分兩種情況,第一種,該方法本身就不關聯任何測試用例,不做任何提示;第二種,該方法關聯了一些測試用例,那麼考慮到方法有可能只是重構或者更名的情況,這部分關聯的測試用例在沒有被刪除的情況下,也是需要進行迴歸的。

阿里雲某核心雲產品,通過使用精準測試的方案,一個迭代了一週左右的程式碼變更,從原先每次 CI 需要全量執行 3700+用例,到每次 CI 可以精準的執行變更影響的用例範圍。速度提升了近一倍,測試範圍縮小到不到原先的 1/6。


提升測試有效性

我們希望編寫和執行的測試用例能夠有效的覆蓋程式碼的邏輯,其中重要的一個著手點是測試覆蓋率,通過測試覆蓋率來暴露問題,並促進問題的解決。

測試覆蓋率

測試覆蓋率,在本文中,指的是程式碼的覆蓋率。即行覆蓋率,分支覆蓋率等。

此外,本文中所有涉及覆蓋率採集的示例都以 Java 為例。

如何收集完整的覆蓋率

一個應用下通常存在多種不同型別的自動化測試集

  • 單元測試
  • 手工測試
  • API 測試
  • WebUI 測試
  • 其他

為了能夠準確的反映一個應用的完整覆蓋率,需要對上述多種自動化測試的結果進行聚合。在阿里,每一個測試的執行都會關聯到相應的應用,從而可以對測試結果進行聚合。

為了能夠收集所有型別的測試覆蓋率,我們做了以下事情:

單元測試

對於單元測試來說,覆蓋率資料產生在單測執行的機器上,我們會根據執行機上的原始程式碼資訊,編譯後的 class 資訊,單測執行後產生的覆蓋率資料原始檔案,以及變更的程式碼資訊,計算出單元測試的覆蓋率報告。

手工/自動化測試

我們實現了一個覆蓋率採集客戶端,和一個覆蓋率採集/報告計算解析的覆蓋率平臺。通過運維平臺將覆蓋率採集客戶端部署到應用的整合環境,在應用啟動時會掛載一個 javaagent 程序。當我們在任意測試平臺觸發任意型別的自動化測試時,會通知覆蓋率平臺與覆蓋率採集客戶端進行互動,完成覆蓋率計算原始資料的採集與解析。

另外,在進行釋出卡點時,我們會合並相應的單測覆蓋率形成完整的覆蓋率報告。

測試覆蓋率能給研發過程帶來哪些價值

  • 分析未覆蓋部分的程式碼,從而反推在前期測試設計是否充分,沒有覆蓋到的程式碼是否是測試設計的盲點,為什麼沒有考慮到?需求/設計不夠清晰,測試設計的理解有誤,工程方法應用後的造成的策略性放棄等等,之後逐步補充測試用例。
  • 程式碼覆蓋率高不能說明程式碼質量高,但是反過來看,程式碼覆蓋率低,程式碼質量不會高到哪裡去,可以作為測試自我審視的重要工具之一。
  • 分析變更程式碼的覆蓋情況,從而保證對變更的測試充分,增強釋出成功率與信心。

除了上述的“測試覆蓋率”,還可以使用相同的技術來統計“線上業務對程式碼的覆蓋情況”。也就是統計出來有哪些程式碼是被真正的線上業務所用到的,哪些是從來沒有被呼叫到的。從而檢測出程式中的廢程式碼,可以逆向反推在程式碼設計中思維混亂點,提醒設計/開發人員理清程式碼邏輯關係,提升程式碼質量。

增量覆蓋率

有了完整的測試覆蓋率資料之後,就可以讓它發揮作用了。但脫離了具體的場景,單獨追求一個較高的測試覆蓋率數值是沒有意義的。如果一味的追求較高的覆蓋率的數值,往往帶來的的是用例的過度設計。如何健康有效的讓專案的測試覆蓋率穩步的提升,在阿里巴巴內部,我們更多的是採用關注增量覆蓋率的方式來提升整體的測試覆蓋率。

什麼是增量覆蓋率

增量覆蓋率是指,某一次測試過程中,變化的程式碼的測試覆蓋情況。

變化的程式碼=被測分支的程式碼與目標對比分支的 diff(通常目標對比分支是我們最終會合入的分支)。

增量覆蓋率=變化的被覆蓋的程式碼行/變化的程式碼行。

增量覆蓋率的價值

  • 釋出之前是否存在漏測
  • 針對漏測完善用例集
  • 增強變更釋出的成功率與釋出信心
  • 通過追求增量覆蓋率進而提高被測應用的整體測試充分度

增量覆蓋率的應用

在單元測試的時候,會有單元測試的增量覆蓋率,在測試/預發等環境進行各種介面自動化/UI 自動化/流量回放/手工測試時,也會有增量覆蓋率產生。當增量覆蓋率與持續交付流水線進行結合時,能夠有效的保障專案質量是在往好的趨勢發展。

在阿里巴巴內部的實踐中,我們通常會在 CICD 流水線中的關鍵階段設定各類卡點,保障在多人協作的場景下,每個開發同學提交進入整合的程式碼經過充分的自測。在上線前的整合階段,進入的程式碼在整合環境中被充分驗證後,才會被允許釋出上線。

通過增量覆蓋率的反饋,開發/測試同學可以針對性的去補充各類測試用例,儘可能的保障在各階段不存在測試遺漏。同時,在不斷的完善測試集的情況下,專案的整體測試覆蓋率也會得到健康有效的提升。

線上覆蓋率

覆蓋率的採集我們通常不會應用到線上環境中,但是如果將覆蓋率採集放到線上環境,又能演化出應用瘦身的場景,幫助我們從另外一個角度提升效率。

通常線上業務的服務都會部署多個副本,為了減少風險,我們會在其中的少量副本上進行覆蓋率採集。經過一個較長的採集週期後,會生成線上覆蓋率報告。在這個時候可以認為被覆蓋到的程式碼都是有效程式碼,而剩下的那些長時間沒有流量覆蓋的程式碼,需要謹慎的考慮刪除/重構。通過這樣的方式去精簡我們的程式碼,從而降低維護成本。

在阿里巴巴內部,當我們決定對某些維護困難或者腐化明顯的應用進行重構時,都會進行一段時間的線上覆蓋率採集,並根據報告去指導我們進行程式碼重構,程式碼瘦身。

小結

分散式測試為測試速度插上了翅膀,精準測試有效的識別出了測試的範圍,增量覆蓋率又為測試的不斷完備提供了有利的指引,線上覆蓋率幫助我們有效的進行應用瘦身。充分利用好這些技術手段進行測試提效,可以讓持續交付的過程更加的順暢。

【關於雲效】

雲效,雲原生時代一站式BizDevOps平臺,支援公共雲、專有云和混合雲多種部署形態,通過雲原生新技術和研發新模式,助力創新創業和數字化轉型企業快速實現研發敏捷和組織敏捷,打造“雙敏”組織,實現 10 倍效能提升。

立即體驗