多環境多需求並行下的代碼測試覆蓋率統計工具實現

馬蜂窩技術原創內容,更多幹貨請關注公衆號:mfwtech

測試覆蓋率常被用來衡量測試的充分性和完整性,也是測試有效性的一個度量。「敏捷開發」的大潮之下,如何在快速迭代的同時保證對被測代碼的覆蓋度和產品質量,是一個很是有挑戰性的話題。前端

在馬蜂窩大交通、酒店等交易相關業務中,項目的開發和測試實踐一樣遵循敏捷的原則,迭代週期短、速度快。所以,如何依據測試覆蓋率數據幫助咱們有效判斷項目質量、瞭解測試狀態、提高迭代效率,是咱們一直很重視的工做。java

Part.1 測試覆蓋率統計中的挑戰

對於功能測試而言,一般能夠經過充分了解需求、完善的測試用例、接口測試、Review 技術方案等來保證測試充分性。但隨着業務規模快速發展,業務邏輯愈來愈複雜,系統級別交互愈來愈多,這些方法都不能保證全部的代碼必定被所有測試過,也給測試人員帶來極大挑戰。數據庫

說到這兒和你們分享一個由於測試覆蓋不充分,影響到線上業務的真實案例。事件原由是項目提測階段一個微服務 Sonar 掃描沒經過,開發同窗爲了修復 Sonar 發現的問題而重構了一部分歷史代碼,卻致使一個原有發券需求的錯誤。當天下午運營觸發發券後 Bug 出現直接致使生單不可用,而且持續了將近一個小時。這裏的問題就是發券功能與這次需求無關,開發人員修改代碼後測試人員不知道,也沒有通過測試,但跟隨本次需求一塊兒上線了,測試用例沒法覆蓋到。後端

經過這個例子能夠明顯地看到正確統計被測代碼覆蓋率的重要性。當前市面上統計覆蓋率的工具不少,但應用到咱們的實際場景中一般存在如下問題:瀏覽器

  1. 大部分第三方工具都是以支持提測前單元測試的覆蓋率統計爲主,而支持提測後測試覆蓋率的工具則比較缺少
  2. 第三方工具提供的覆蓋率基本都是展現全量的,但大部分狀況下,測試人員重點關注的應該是本次新增和修改的部分,而不是耗費過多精力在未修改的部分上;
  3. 爲了支持多需求並行測試,大交通後端服務採用 QA 隔離環境,而市面上尚未支持多需求隔離環境並行測試的測試覆蓋率統計工具

所以,大交通測試組決定自研工具進行被測代碼的覆蓋率統計,用代碼覆蓋結果反向地檢查測試人員測試用例的覆蓋度和開發人員代碼的冗餘度,更精準地定位和分析問題,保證產品質量。服務器

Part.2 覆蓋率統計工具設計

結合咱們的實際場景,覆蓋率統計工具的實現目標以下:架構

  1. 大交通業務後端代碼使用 Java 語言開發,主要的業務處理邏輯都在後端,因此工具要優先支持 Java 代碼覆蓋率統計
  2. 能夠統計提測後測試過程當中不一樣類型測試的覆蓋率,包括:手工測試、迴歸測試、接口測試、UI 自動化測試等等
  3. 支持全量、增量覆蓋率統計
  4. 支持多需求多環境並行測試,同時統計覆蓋率
  5. 用戶不侷限於測試人員,而是全部有測試需求的人員,包括開發和測試等
  6. 支持自動化統計,簡化操做步驟,無需學習成本,報告簡單易懂

咱們將覆蓋率統計工具命名爲 jCover,並將其引入 CI/CD 體系,與內部 Java 平臺項目管理及持續集成系統 MONE 打通。工具設計以下圖所示:微服務

圖 1:覆蓋率工具總體架構圖工具

覆蓋率統計的大體流程爲首先經過獲取多環境服務的配置信息,生成指定環境服務的測試覆蓋率文件,而後根據須要生成全量覆蓋率報告和增量覆蓋率報告,最後,存儲測試覆蓋率報告到指定環境目錄下。單元測試

Part.3 主要功能及實現方式

jCover 的主要功能包括:

  • 支持多需求多環境並行測試下,同時統計覆蓋率
  • 支持全量覆蓋率統計
  • 支持增量覆蓋率統計
  • 支持自動/手動統計覆蓋率
  • 覆蓋率報告統一管理

下面圍繞以上功能點,爲你們介紹 jCover 的做用、特色和具體實現方式。

1. 覆蓋率工具平臺化

爲了簡化操做步驟下降學習成本、報告簡單易懂,jCover 支持界面化操做,能夠手動生成測試覆蓋率報告和查詢測試覆蓋率報告;查詢測試覆蓋率報告入口統一,代碼測試覆蓋率數據清晰,方便數據統計和量化。

圖 2:覆蓋率報告查詢頁面

2. 支持多需求多環境下的並行測試

因爲使用敏捷迭代,項目多、並行率高,大交通全部微服務均引入測試環境隔離插件,同時支持多項目並行測試。所以,jCover 須要支持多環境並行的測試覆蓋率統計。

具體來講,每一個測試項目都會有一個單獨的環境標識,以隔離環境標識+環境類型+服務名稱惟一肯定一個覆蓋率統計單元;每個覆蓋率統計單元都會生成對應的測試覆蓋率統計報告,測試覆蓋率統計報告被存儲到 jCover 部署的服務器中,存儲位置是環境標識對應的服務目錄下;同一個服務的不一樣提測分支同時在多項目中測試時相互間的覆蓋率報告不會被覆蓋。

多環境並行流程圖見下圖(目前只支持 QA 環境覆蓋率統計):

圖 3:多環境並行流程圖

例如:隔離環境 gjssqz 和隔離環境 supplyrefund 能夠同時進行測試覆蓋率統計,隔離環境標識+環境類型+服務名稱指定了每一個環境下的單個服務測試覆蓋率統計結果。

覆蓋率工具 UI 展現以下圖:

圖 4:用「隔離環境標識+環境類型+服務名稱」來標識和統計覆蓋率

3. 全量覆蓋率統計

在測試時有時候須要關注全量代碼的測試覆蓋率,代碼全量覆蓋率統計過程以下:

(1)查詢服務信息

jCover 經過內部 Java 平臺項目管理及持續集成系統 MONE 來查詢被測微服務的信息:

  • 爲了減輕對 MONE 系統的壓力,設定每日一次定時拉取全量服務信息,將隔離環境標識、服務名稱、容器 IP、監聽端口、環境類型和狀態存儲到數據庫。
  • 生成覆蓋率報告時根據隔離環境標識和服務名稱從 MONE 單服務信息拉取接口查詢最新的容器 IP。若是數據庫沒有就新增服務信息,若是數據庫有就更新服務對應 IP。

(2)收集覆蓋率數據

爲了作覆蓋率統計,須要從微服務部署的容器中下載測試覆蓋率 Dump 文件。咱們採用的解決方案是使用 JavaAgent 代理,首先對微服務部署的容器進行了改造,使得容器支持 JavaAgent 功能;其次爲了動態插樁記錄被測代碼的運行結果,在被測微服務的 JVM 啓動腳本中增長 JavaAgent 參數。

覆蓋率工具根據 IP 和監聽端口經過 JavaAgent 代理從容器中下載 Dump 文件,以環境和服務標識惟一 Dump 文件,並存儲到 jCover 所在的服務器。在下載覆蓋率數據時採用追加方式,若是該 Dump 覆蓋率文件已存在,那麼該輪的覆蓋率數據會直接在文本末尾進行追加,便於統計整個測試過程的代碼覆蓋結果。

(3)根據全量覆蓋率文件生成全量覆蓋率報告

  1. MONE 從微服務容器中拷貝 Class 文件到 jCover 所在服務器指定目錄
  2. jCover 經過 Class 文件和 Dump 文件生成全量覆蓋率文件
  3. 根據全量覆蓋率文件生成全量的測試覆蓋率報告,把全量的測試覆蓋率報告以「隔離環境標識+服務名稱+順序 ID」的維度存儲到 jCover 所在服務器的指定目錄
  4. 最後配置靜態資源映射規則生成測試覆蓋率報告 URL 並把測試覆蓋率報告 URL 存儲到數據庫中

用戶打開測試覆蓋率工具前端界面就能夠在瀏覽器中查看步驟 D 生成的覆蓋率報告了,綠色表示被覆蓋,紅色表示未被覆蓋,黃色表示部分覆蓋:

圖 5:全量測試覆蓋率報告展現

4. 增量覆蓋率統計

業務發展到必定階段後,代碼量級很大。主幹代碼咱們默認是正確的代碼。當一個新需求提測後,測試人員更關注的實際上是針對本次需求更改的代碼的覆蓋率而不是所有代碼的覆蓋率,想從全量覆蓋率報告中找出本次更改的增量代碼的覆蓋率是很是困難的。基於此問題咱們開發了增量覆蓋率統計功能。

增量覆蓋率統計和全量覆蓋率統計有三個相同的步驟:查詢服務信息、收集覆蓋率數據、生成全量覆蓋率文件。生成全量覆蓋率文件後,增量覆蓋率統計的不一樣點是增長了如下處理:增量代碼獲取、生成增量覆蓋率報告,具體實現以下:

(1)Diff 增量代碼

  1. 分別獲取每一個微服務的 master 主幹和測試分支內容,Diff 測試分支對象和 Master 分支對象,獲得增量代碼
  2. 濾除增量代碼中的非.java 文件
  3. 循環遍歷增量代碼獲得變化行,標識行變化類型包括:新增、更新

(2)生成增量覆蓋率報告

  • 根據增量代碼變化行標識無變化的方法
  • 在改變的代碼行(改變包括增長和更新)行首加上對應的標識:「增長」的代碼以「+++」標識,「更新」的代碼以「U」標識,同時刪除無變化的方法,生成增量代碼覆蓋率報告

圖 6:增量覆蓋率流程

下圖是交易服務增量覆蓋率報告的截圖示例,從圖中清晰看出增量行和更新行的測試覆蓋率狀況。

圖 7:增量覆蓋率報告展現

5. 支持手動/自動統計覆蓋率

當測試人員須要查看最新的測試覆蓋率時,能夠經過「jCover - 生成測試覆蓋率報告」的入口手動觸發生成測試覆蓋率報告。

圖 8:手動統計覆蓋率圖形化界面

在一個需求的實際測試中被測的微服務一般有多個。由於修改 Bug 等緣由,被測微服務常常須要重啓,重啓後容器銷燬,JavaAgent 插樁後的文件也會被刪除致使重啓前覆蓋的代碼沒法被統計。

若是每次重啓每一個被測微服務前都須要測試人員手動生成覆蓋率報告的話,是個很大的工做量也會常常被遺忘。所以 jCover 經過和發佈系統結合實現了覆蓋率自動統計功能。具體實現方法爲 jCover 提供了自動生成覆蓋率文件接口,在服務重啓部署時後端發佈系統調用此接口,實現自動統計覆蓋率,無論服務重啓多少次均可以把每次測試時覆蓋的代碼所有統計到。

以前大交通的後端服務發佈系統爲 Jenkins,後續升級爲了 MONE,兩種發佈系統下均支持服務部署時自動統計覆蓋率。

Part.4 工具效果

通過一段時間推廣使用和優化,如今大交通全部的需求提測後均使用 jCover,主要體現出如下幾點優點:

  • 能夠支撐不一樣類型的覆蓋率測試。jCover 能夠統計手工測試、接口測試、迴歸測試、UI 自動化測試等各類類型測試的所有覆蓋率,展現爲一份覆蓋率報告。
  • 及時發現漏測代碼。經過使用測試覆蓋率工具能夠發現測試用例未覆蓋的代碼,反推測試用例缺失。例如在「虛艙管理」項目中國際交易支付前校驗失敗發送 MQ 消息沒有覆蓋,測試人員補充了支付前校驗失敗發消息的測試用例;在「國際搜索坑位供應商及價格優先級設置」項目中發現因爲 Mock 數據的侷限性, 帶有輔營的加價代碼未覆蓋,補充了機票+輔營的測試用例,提升測試覆蓋度。
  • 發現開發的冗餘代碼。例如:在「國際機票重複預訂優化項目」中發現冗餘代碼,getBaseOrderDetail 方法無調用方,開發進行了刪除。
  • 及時發現測試中的問題並改進,提升測試效率。在「國內供應商資源統一化」項目中測試人員執行了不少測試用例後,使用 jCover 查看覆蓋率報告發現應該覆蓋的代碼未被覆蓋,與開發溝通後發現控制這部分代碼邏輯的開關是「關閉」狀態,此開關應該是在「打開」狀態進行測試
  • 爲上線代碼審批提供數據參考。當團隊成員申請代碼上線時,開發 TL 能夠重點關注未覆蓋部分代碼,減小線上問題發生。
  • 輔助提高測試人員對被測代碼的熟悉度。

Part.5 近期規劃

目前 jCover 只支持查看每個類覆蓋行和未覆蓋行是什麼,可是對於一個微服務總體行覆蓋率是多少沒有統計,咱們正在開發增量覆蓋率百分比,幫助開發和測試作出準確的判斷。目前也在調研前端的覆蓋率統計,下一步將實現前端的覆蓋率統計工具 jCover。

在平常需求測試中能夠採用測試(手工測試、接口測試、迴歸測試等)+jCover 覆蓋分析的測試方法來完善測試場景,減小測試遺漏,確保測試的充分性,但須要注意的是 jCover 統計只能展現哪些代碼被覆蓋了,代碼的正確性仍是須要用例的執行結果正確來保障;還有時候開發會漏開發某部分需求,此時依靠 jCover 是沒法發現這部分遺漏代碼的,所以除了 jCover 以外能夠經過參與技術評審、編寫用例時參考產品功能矩陣圖等多種手段發現問題,全方位保障被測代碼的質量。

以上就是對馬蜂窩大交通測試覆蓋率統計工具 jCover 的分享。固然,統計代碼覆蓋率僅僅是一種手段,覆蓋率高不必定表明質量好,但覆蓋率不高的代碼質量風險確定很高。只有清楚在覆蓋率統計數據背後反映出的問題,才能從根本上保證軟件總體的質量。

本文做者:代春美,馬蜂窩測試部-交易測試工程師;孫海燕,馬蜂窩測試部-交易測試團隊負責人。

相關文章
相關標籤/搜索