代碼覆蓋率在敏捷式軟件開發過程中的實踐流量

01

前言

 

代碼測試覆蓋率是一種度量,它描述了對程序源代碼的測試程度,是白盒測試的一種手段,能夠直觀暴露測試用例無法覆蓋到的代碼塊。作爲提升代碼質量的利器,愛奇藝開發團隊和QA團隊在如何接入、使用等方面做了一些探索性的嘗試與實踐。


目前代碼覆蓋率大多停留在整體層面,沒有細化到更小的粒度。在協同開發過程中,如果能精細到需求粒度級別覆蓋率,關聯到具體的負責人,將能有效提高測試效率和精度。


本文將從代碼覆蓋率接入和使用的角度,敘述瞭如何結合代碼管理、項目管理等DevOps工具進行精細化代碼覆蓋率統計以幫助提高代碼質量。

 

  02

背景

互聯網公司軟件開發模式多爲敏捷式或者迭代式開發模型,彌補了傳統開發模式的一些弱點,具有更高的成功率和開發效率,能夠先儘快地將產品投向市場,再通過用戶的廣泛參與,不斷修改優化產品,實現產品的快速迭代,更好地適應用戶市場變化。

 

不過隨着項目的迭代,功能場景變多,代碼工程會愈加龐大複雜,代碼質量也因此至關重要。如何在開發測試周期提升代碼質量,代碼測試覆蓋率作爲一個可以衡量代碼質量的標準,如何接入使用覆蓋率數據,是一個值得深入探索實踐的方向。


  • 定義


> 代碼覆蓋(英語:Codecoverage)是軟件測試中的一種度量,描述程序中源代碼被測試的比例和程度,所得比例稱爲代碼覆蓋率。


  • 代碼覆蓋率的意義


1. 完善測試用例:從代碼覆蓋率報告可以明確,哪些代碼是執行過的,哪些代碼是沒有執行過的。對於沒有執行過的代碼,測試人員需要思考下是代碼邏輯設計問題還是測試用例問題。如果是代碼邏輯問題,那麼需要與開發人員和產品人員溝通,達成需求的一致性理解。如果是測試用例問題,那麼需要補足缺失的測試場景,儘可能保證所有重要的場景都覆蓋到了,避免未測試的代碼上線造成服務故障。

 

2. 提升代碼質量:開發人員從覆蓋率報告可以獲得代碼的執行流程走向,幫助理解代碼邏輯。分析生產環境的代碼覆蓋率報告,還可以區分出真實的用戶請求執行覆蓋情況,區分“有用/無用”代碼,有利於優化簡化代碼邏輯。

 

3. 代碼質量標準:代碼覆蓋率是一個確切的數值,將模糊定義的代碼質量用精準的數據來量化,是白盒測試和代碼質量的衡量指標。

 

從代碼覆蓋率報告可以明確,哪些代碼是執行過的,哪些代碼是沒有執行過的,從未執行過的代碼可以推算出測試用例是否充足,幫助測試人員理清代碼邏輯和完善測試用例。代碼測試覆蓋率作爲一項衡量代碼質量的重要標準,可以在測試階段發現隱藏問題,將隱性問題消滅在萌芽狀態,減少線上問題發生。

  •  現狀


開源的覆蓋率實現工具有很多,但是在實際使用中,還需要做比較多的準備工作,經常遇到以下問題:

 

  • 無法區分增量代碼

 

增量代碼是指新修改的代碼,從全量代碼中區分出增量代碼的好處是,讓使用者只關注於自己負責的代碼,去除干擾,減少人工篩選成本。而覆蓋率工具只是用於生成代碼覆蓋率(全量)的工具,沒有區分增量代碼。

 

  • 使用成本高

 

覆蓋率報告只是一份綜合的報告,使用者通常只會關心自己的代碼覆蓋率,在多人協同開發過程中,如何將某一處代碼覆蓋率與具體的需求(開發人員、測試人員)關聯是一個問題。

 

  • 測試環境多人協同多次修改變化性大,維護成本高

 

在實際的開發測試周期中,可能會出現修改代碼再測試,測試後再修改代碼的現象,代碼覆蓋情況是一個變化的過程。考慮到覆蓋率工具只能對固定的代碼進行收集,如何減少此變化過程的維護成本是需要解決的。

 

  03

目標和功能

基於以上問題,愛奇藝開發團隊在覆蓋率生成工具基礎上,整合DevOps工具,以相對較小的成本快速接入生成代碼覆蓋率,並支持計算生成代碼分支級別、需求級別的精細粒度增量代碼覆蓋率報告。以下以Java爲例,簡單闡述實現方案和原理。


業務架構


  • 簡化接入流程   

 

使用方僅關心如何將生產出來的java文件、class文件和exec文件推送到指定位置,即可自動化生成詳細的覆蓋率報告。

 

  • 增量代碼報告

 

利用diff算法,區分出增量代碼,生成單獨的增量報告和全量報告。


[增量&全量代碼報告]


  • 代碼分支級別代碼覆蓋率

 

計算測試分支中(某一個代碼分支所佔的)代碼覆蓋率。


[代碼分支級別報告]


  • 需求級別代碼覆蓋率

 

計算Jira中某一個需求(issue涉及到的)代碼覆蓋率。


[需求級別報告]

  04

技術實現

下面以Java爲例,簡要說明技術實現原理。考慮到目前維護性比較好的覆蓋率工具,選擇了JaCoCo開源工具。


運行原理


[運行原理]


JaCoCo生成覆蓋率報告需要三個依賴數據:源碼Java文件、編譯class文件和代碼探針打樁執行的結果exec文件。


1. 源碼Java文件和編譯class文件是通過CI job的方式push到服務端,exec文件是jvm 通過tcp連接將內存數據導出到服務端。

2. 彙總三部分文件,利用JaCoCo工具生成代碼的全量代碼覆蓋率報告。

3. 從Gitlab平臺獲取到測試分支與master分支代碼diff結果,即增量代碼,結合其他三部分數據,生成增量代碼覆蓋率報告。

4. 通常測試代碼分支是多人協作的結果,很多feature代碼分支都會合併到測試分支中,再通過git commit溯源關係,得到增量代碼的初始來源分支,結合覆蓋率報告可以得到每個代碼分支的覆蓋率報告。

5. 最後,將Jira需求和代碼分支關聯,得到需求涉及的代碼覆蓋率報告。

 

核心技術實現


  • JaCoCo改造


JaCoCo覆蓋率報告生成條件是Java源代碼、編譯後的Class文件和生成的exec(jvmexecution data,.exec類型)覆蓋率數據。其中exec覆蓋率數據是由probe探針生成的二進制文件,包括SessionInfo(此次數據的來源id、開始時間、結束時間)和 ExecutionData(每個類文件對應的探針boolean類型數組)。Jacoco官方給出導出exec數據的方式有三種:File System、TCP Socket Server和TCP SocketClient。現有的幾種方式存在一定侷限性,無法滿足靈活自動上報的要求,並且如果jvm異常關閉,會導致數據直接丟失。所以,在TCP Socket Client基礎上進行優化改造,支持了Schedule定時上報功能,通過配置化定時參數,允許隨時上報,靈活配置。


  • 增量代碼覆蓋率的生成


利用git工具對比測試分支與master分支,獲取增量代碼(新增和修改的代碼)。根據增量代碼找出匹配的Jacoco執行exec文件,再利用asm框架,分析計算得到增量覆蓋率數據。


  • 代碼分支級別覆蓋率


得到增量代碼覆蓋率後,再通過git commit信息,溯源找到所有代碼的初始提交分支。


  • 需求級別代碼覆蓋率

 

爲了便於關聯代碼和需求,以及快速識別相關開發和測試負責人,對代碼分支的命名做了一些規範。

 

從代碼分支中檢索出符合規範的代碼,查詢Jira項目管理系統,進行關聯。Jira需求對應的代碼分支級別覆蓋率即爲需求的代碼測試覆蓋率。

 

 需求類型 | 分支命名前綴 | 示例

---|---|---

跟版需求 | feature/v{version}/{issue_id}_xxx|  feature/v11.7.0/JIRA-9443_xxx

純後端需求 | feature/backend/{issue_id}_xxx |feature/backend/JIRA-9444_xxx


  • 使用要求


爲了提升代碼質量和減少線上問題的出現,對增量代碼的覆蓋率提出了比較嚴格要求,低於標準的情況都需要備註說明原因。

| 類型 | 標準 |

---|---

| 版本交付標準 | 所有代碼增量覆蓋率>=90% |

| 測試通過標準 | 需求分支增量覆蓋率>=90% |

| 代碼上線標準 | 代碼分支增量覆蓋率>=90% |


覆蓋率高不等同於代碼質量高,但覆蓋率不高說明存在有未測試過的代碼,這些代碼上線後可能會成爲服務穩定性方面的隱性問題。但是一味得追求高覆蓋率也是不可取的。一方面,無效的代碼(例如判空類型的代碼)可能無法覆蓋;另一方面,追求高覆蓋率付出的人力成本會比較高。


  • 需求測試上線流程


    [需求測試上線流程]


測試人員根據需求內容制定測試用例,在測試環境進行測試驗證完畢後,根據生成的需求測試覆蓋報告,衡量是否達標(檢查覆蓋率是否達到預期、關鍵的分支判斷是否覆蓋等)。如果不達標,需要進行補充用例或者需要開發人員進行代碼邏輯修復,再進行重複測試,達標後的需求方可進行審批上線到生產環境。在此過程中,平臺會自動生成該需求關聯的變更代碼覆蓋情況,避免了複雜協作環境下其他人代碼對該需求影響,測試人員可以較快地發現未覆蓋代碼,並與上線流程打通,減少未覆蓋代碼帶來的隱性問題上線情況,一定程度上保證了服務質量。


  05

總結&規劃

本文介紹了愛奇藝開發團隊和QA團隊在測試覆蓋率方面的探索和實踐,在代碼測試覆蓋率工具基礎深入研究改造,結合其他開發協作平臺,支持更快速的集成接入方式,計算展示了增量代碼報告、分支覆蓋報告、需求覆蓋報告等更多維度報告,爲使用者提供了極大的便利性。在平臺搭建後,平臺能快速接入更多的服務,爲測試人員提供更多維度的參考衡量標準,重點後端應用服務代碼測試覆蓋率從不足70%提升到90%+,在一定程度上有效地保證了服務質量。

 

目前的覆蓋率數據是來源於測試環境的,只限於開發測試周期使用。後續會在生產環境的代碼覆蓋率方向上做出一些嘗試,例如,利用生產環境的代碼執行的覆蓋率報告自動化篩選一些關鍵接口請求作爲撥測用例、將生產環境的流量請求測試環境對比生產環境和測試環境的覆蓋率報告差別以衡量改動影響等。


看完心動了嗎?
戳👇“ 閱讀原文”直達招聘頁面
即刻加入愛奇藝!

也許你還想看
愛奇藝是如何在活動中臺實踐低代碼的?
代碼質量提升之道——代碼覆蓋率原理與移動端工程實踐
開發效率提升50%以上,愛奇藝官網主站的Nuxt實踐
 關注我們,更多精彩內容陪伴你!

本文分享自微信公衆號 - 愛奇藝技術產品團隊(iQIYI-TP)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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