最近团队做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小时。然而,这也并不是绝对的,有时候为了快速交付功能,可能会接受一些技术债务。 八、研发度量指标大全九、业内做代码扫描和度量分析的专业软件
代码质量阀
十、Azure Devops中集成SonarQube代码分析和上报
当然,代码质量阀是可以定义的
标签:总结,函数,覆盖率,代码,债务,复杂度,度量 From: https://www.cnblogs.com/tianqing/p/17893189.html