關於代碼質量度量和分析的一些總結

最近團隊做CMMI3認證,這期間涉及到了代碼質量度量。花了點時間做了總結,分享給大家。

先看一張整體的圖,然後逐個指標展開說明。

 一、單元測試覆蓋率

單元測試覆蓋率(Coverage)是一個度量單元測試覆蓋了多少代碼的指標。它是一種衡量測試質量的方法,用來指示我們的測試用例覆蓋了代碼的多大部分。 覆蓋率的計算方式通常包括以下幾種: 行覆蓋率(Line Coverage):測試覆蓋了多少代碼行。 分支覆蓋率(Branch Coverage):測試覆蓋了多少if、switch等決策點的所有可能路徑。 函數覆蓋率(Function Coverage):測試覆蓋了多少個函數或方法。 語句覆蓋率(Statement Coverage):測試覆蓋了多少個語句。 覆蓋率越高,表示的測試用例覆蓋的代碼越全面,代碼的質量可能越好。但是,這並不意味着覆蓋率100%就一定沒有問題,因爲覆蓋率只是告訴我們測試了哪些代碼,而不是告訴我們測試的質量如何。另外,有些代碼可能很難達到高覆蓋率,例如異常處理代碼等。 一般來說,覆蓋率應該儘可能的高,一般認爲80%是一個比較好的目標。
 
二、代碼複雜度
Cyclomatic Complexity(圈複雜度)和 Cognitive Complexity(認知複雜度) 都是軟件度量中的複雜度度量指標。其中: 1. Cyclomatic Complexity圈複雜度在數量上表現爲代碼獨立執行路徑條數。 例如,每個“if”語句就會添加了一條額外的代碼路徑。圈複雜度越高,程序代碼的判斷邏輯就越複雜。此外,路徑越多,就需要編寫更多的測試用例來實現更高的代碼覆蓋率。 每個函數的平均圈複雜度是一個指標,可以比較程序之間的複雜性。 圈複雜度在一定程度上展示了程序代碼的“可維護性”。 2. Cognitive Complexity(認知複雜度)是SonarQube提出的一種新的複雜度度量方法,它試圖量化代碼對人類理解的難度,而不僅僅是代碼的結構複雜度。認知複雜度的計算考慮了程序的結構複雜度(如循環、判斷分支等),以及程序的可讀性(如代碼的冗餘性、是否遵守最佳實踐等)。例如,一個包含嵌套循環和條件判斷的函數,其認知複雜度會高於只包含順序執行代碼的函數。另一個例子是,使用了難以理解的短變量名或者包含冗長的函數和類,這些都會增加代碼的認知複雜度。
 
三、代碼重複度
代碼重複度是指在代碼庫中有多少代碼是重複的,也就是相似或完全相同的代碼塊出現的次數。 1. 代碼重複通常是由於複製和粘貼編程(也稱爲“剪貼板編程”)導致的,這種情況下,開發人員可能會複製一個函數或一段代碼,然後稍作修改以滿足新的需求。雖然這種方法可以快速解決問題,但它通常會導致維護困難和錯誤的增加。如果在原始代碼中發現了一個錯誤,那麼所有複製的代碼都需要進行相同的修復。。 代碼重複度 = (重複的代碼行數 / 總代碼行數) * 100% 這個比例越高,表示代碼重複的程度越嚴重。 在防止代碼重複方面,通常的最佳做法是使用函數或類來封裝重複的代碼,並在需要的地方調用這些函數或類。這樣,如果需要修改代碼,只需要在一個地方進行修改,而不需要在多個地方進行相同的修改。
 
四、代碼壞味道
"Code Smells"或"代碼壞味道"是一種代碼質量度量,用來形容那些在代碼中可能存在問題的代碼片段。它並不一定表示代碼有錯誤,而是表示代碼的設計可能存在問題,這些問題可能會使得代碼難以理解、難以維護、難以修改。 以下是一些常見的代碼壞味道的例子: 複雜的條件邏輯:如果一個函數或方法中存在過多的if/else或switch語句,可能表示這個函數或方法承擔了過多的責任,需要進行重構。 長方法:一個方法過長,可能難以理解和維護。一般來說,一個好的方法應該只做一件事情,並且做得好。 重複的代碼:如同前面提到的代碼重複度,代碼重複是一種常見的代碼壞味道,應該通過提取函數或類來消除。 神祕命名:如果變量、函數或類的命名不清楚,可能會導致理解和維護的困難。好的命名應該清晰表達其目的和用途。 過大的類或模塊:如果一個類或模塊過大,可能表示它承擔了過多的責任,需要進行分解。 
 
五、安全漏洞
Vulnerabilities或稱爲安全漏洞,是指在代碼中可能存在的安全風險。這些風險可能被攻擊者利用,從而對系統的數據和功能構成威脅。 SQL注入:如果代碼中直接拼接SQL語句,而沒有對用戶輸入進行適當的處理,那麼攻擊者可能會通過輸入惡意數據來篡改SQL語句,從而進行非法查詢或修改數據。 跨站腳本(XSS):如果網站直接輸出用戶的輸入,而沒有進行適當的轉義或過濾,那麼攻擊者可能會通過輸入包含JavaScript代碼的數據,從而在其他用戶的瀏覽器中執行這些代碼。 路徑遍歷:如果代碼中使用了用戶的輸入來構造文件路徑,那麼攻擊者可能會通過輸入特殊的路徑(如"../")來訪問到不應該被訪問的文件。 不安全的反序列化:如果代碼接受並反序列化了用戶提供的數據,那麼攻擊者可能會通過提供惡意的數據來執行任意代碼。 ......
 
六、技術債務
Technical Debt,或稱爲技術債務,是一個比喻,用來描述因爲選擇了快速或簡單的解決方案,而非最佳的解決方案,從而在未來需要付出更多的工作來解決這些問題的情況。這就像財務債務一樣,如果不及時償還,隨着時間的推移,"利息"會越來越多。 技術債務是一個重要的度量指標,用來估算修復所有代碼壞味道所需的時間。例如,如果一個代碼壞味道需要花費30分鐘來修復,那麼這個代碼壞味道就會產生30分鐘的技術債務。所有代碼壞味道的技術債務累加起來,就是整個項目的技術債務。 技術債務可以幫助團隊理解和量化代碼質量問題的影響,從而做出更好的決策。團隊可以基於技術債務來決定是否需要對某部分代碼進行重構,或者在新功能開發和技術債務償還之間做出權衡。 需要注意的是,技術債務並非都是壞事,有時候爲了滿足業務需求,適當的接受一些技術債務是可以接受的。關鍵在於,團隊需要意識到技術債務的存在,並且制定計劃來及時償還技術債務,防止其無限制的增長。
 
七、阿里、微軟、Google這些世界級軟件公司的代碼質量度量值 
從公開的編程實踐和代碼質量標準中得到一些啓示。這些公司通常都非常重視代碼質量,並採取各種措施來保證代碼質量,例如嚴格的代碼審查流程、強制的單元測試和代碼覆蓋率要求、詳細的編程規範和最佳實踐等。此外,他們還經常使用自動化的代碼質量檢查工具,如靜態代碼分析工具,來自動檢測代碼中的問題。 單元測試覆蓋率:這些公司通常都要求代碼有良好的測試覆蓋率。例如,Google在其測試博客上提到,他們的一些項目要求代碼的單元測試覆蓋率達到80%以上。 對於代碼複雜度,一般來說,每個函數或方法的複雜度應該儘可能的低。有些組織可能會設定一個具體的閾值,例如,圈複雜度不得超過10。這意味着每個函數或方法的控制流程不應該有超過10個不同的路徑。但是,這並不是絕對的,有時候爲了實現複雜的功能,函數或方法的複雜度可能會較高。 對於代碼重複度,一般來說,應該儘可能的低。有些組織可能會設定一個具體的閾值,例如,代碼重複度不得超過5%。這意味着在所有代碼中,不應該有超過5%的代碼是重複的。但是,這也並不是絕對的,有時候爲了代碼的可讀性和維護性,可能會有一些必要的代碼重複。
對於代碼壞味道,它是一種主觀的度量,取決於團隊對什麼是“好的”代碼的看法。一般來說,代碼壞味道的數量應該儘可能地少。有些團隊可能會設定一個閾值,例如,每1000行代碼中不應該有超過10個代碼壞味道。然而,這並不是絕對的,有時候爲了滿足特定的需求,可能會接受一些代碼壞味道。 對於技術債務,它是一種估算修復所有代碼壞味道所需的時間。一般來說,技術債務應該儘可能地低。有些團隊可能會設定一個閾值,例如,每1000行代碼的技術債務不應該超過10小時。然而,這也並不是絕對的,有時候爲了快速交付功能,可能會接受一些技術債務。
 
八、研發度量指標大全

 

九、業內做代碼掃描和度量分析的專業軟件

SonarQube is a self-managed, automatic code review tool that systematically helps you deliver Clean Code. As a core element of our Sonar solution, SonarQube integrates into your existing workflow and detects issues in your code to help you perform continuous code inspections of your projects. The product analyses 30+ different programming languages and integrates into your Continuous Integration (CI) pipeline of DevOps platforms to ensure that your code meets high-quality standards.

 代碼質量閥

 十、Azure Devops中集成SonarQube代碼分析和上報

 

 當然,代碼質量閥是可以定義的

 

 

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