系列文章目录
LDRA Testbed软件静态分析_操作指南
LDRA Testbed软件静态分析_自动提取静态分析数据生成文档
LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建
LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果
LDRA Testbed软件静态分析_软件质量度量
LDRA Testbed软件静态分析_常见问题及处理
LDRA Testbed软件单元测试_操作指南
LDRA Testbed软件单元测试_常见问题及处理
LDRA Testbed软件集成测试_操作指南
LDRA Testbed软件集成测试_常见问题及处理
粉丝问题解答系列文章… …
其他持续更新中… …
文章目录
- 系列文章目录
- 前言
- 一、Testbed软件质量审查报告概述
- 1.Overall Results
- 2.Reformatted Code Information for File
- 3.Procedure Information
- 4.Comments Associated with Procedures (% of total)
- 5.Ratio of Comments to Executable lines (%)
- 6.Complexity Metrics
- 7.Halsteads Metrics
- 8.Loop/Interval Analysis
- 9.LCSAJ and Unreachability
- 10.Dataflow Information
- 二、重点软件质量项详述
- 1.Cyclomatic Complexity(圈复杂度)
- 2.Essential Cyclomatic Complexity(基本圈复杂度)
- 3.Fan in(扇入数)
- 4.Fan Out(扇出数)
- 5.代码注释率
- 总结
前言
在之前的文章已经讲解了如何使用Testbed进行软件静态分析,包括手动的操作指南,以及如何在Jenkins下搭建自动化的静态分析环境。之前着重讲的是软件静态分析中对软件编码标准的检查情况(比如使用MISRA C/C++等标准),本篇文章将基于Testbed进一步讲解软件质量度量。包括软件质量度量项的整体概述,以及对圈复杂度、扇入数、扇出数等项的重点介绍。
一、Testbed软件质量审查报告概述
1.Overall Results
首先映入眼帘的是“Overall Results - Percentage of Metrics Passing”,即“总体结果 - 通过指标的百分比”,对每个源文件按照“All Metrics”(所有指标)、“Clarity”(清晰性)、“Maintainability”(可维护性)、“Testability”(可测试性)等维度进行结果展示。这些维度的结果是后续所有相关度量项的统计结果,如下图:
Testbed_10.x.x之后的版本的质量审查报告如下:
Testbed_10.x.x之前的版本(如8.x.x、9.x.x等)的质量审查报告如下:
虽然不同版本的质量审查报告显示视图有些差异,但其中的度量项基本相同,此后均以更新版本的Testbed_10.1.0的质量审查报告作为示例进行讲解。
此后的2~10小节是按照每个源文件分别进行质量度量结果的展示。
2.Reformatted Code Information for File
“Reformatted Code Information for File”即“源文件的格式化代码的信息”,testbed对源代码的格式化示例如下:
Testbed会对源代码进行格式化处理后再进行分析;在格式化代码的基础上进行各项度量和分析,这样可以保证工程中的所有代码都是在一致的科学的格式和标准下进行度量和分析,使度量结果更准确。其中包括格式化代码总行数、格式化代码注释总行数、可执行格式化代码行数、不可执行格式化代码行数、函数的总数、原码的总行数、扩展因子(膨胀比率)等。
在软件质量中,Expansion Factor(扩展因子)(膨胀比率)通常指的是软件的可扩展性,即对软件的规约进行修改,以适应变化的能力。这涉及到软件设计和架构的灵活性,以便在需求或环境发生变化时,能够容易地对软件进行扩展和修改。扩展因子通常与软件的可维护性、可复用性和灵活性等质量属性相关。一个具有良好扩展性的软件应该能够容易地添加新功能、修改现有功能或适应新的运行环境,而不需要对整个系统进行大规模的修改或重构。
在评估软件的扩展因子时,可以考虑以下几个方面:
模块化程度:软件是否被划分为清晰的模块,每个模块具有明确的职责和接口。
耦合度:各个模块之间的依赖关系是否紧密,是否容易解耦。
内聚性:模块内部的功能是否紧密相关,是否容易进行功能的增加或修改。
可扩展性设计原则:是否遵循了如开闭原则(OCP)、里氏替换原则(LSP)等面向对象的设计原则,以提高软件的可扩展性。
可测试性:新的或修改的功能是否容易进行测试和验证。
不同的软件项目和团队可能对扩展因子的定义和评估方法有所不同,因此,在具体项目中,需要根据项目的需求和团队的实际情况来定义和评估扩展因子。testbed只是提供了一个参考结果,这个用得比较少,这里只做概念介绍。
3.Procedure Information
“Procedure Information”即“函数信息”,这里按照函数列表的视图进行展示,包括每个函数的可执行的格式化代码行数、基本模块数、基本模块的平均长度、函数的入口个数、函数的出口个数等。
4.Comments Associated with Procedures (% of total)
“Comments Associated with Procedures (% of total)”即“与函数相关的注释”,这里按照函数列表的视图进行展示,包括每个函数的总注释行数、函数头注释行数、函数声明中的注释行数、函数可执行代码中的注释行数、空白行数等。
5.Ratio of Comments to Executable lines (%)
“Ratio of Comments to Executable lines (%)”即“注释和可执行代码行的比率”,这里按照函数列表的视图进行展示,包括每个函数的总注释与可执行代码的比率、头注释与可执行代码的比率、声明注释与可执行代码的比率、代码注释与可执行代码的比率、以及每个函数重新格式化后的可执行代码行数。
6.Complexity Metrics
“Complexity Metrics”即“复杂度度量”,这里按照函数列表的视图进行展示,包括每个函数的基本结点数、基本圈复杂度、结点数、圈复杂度、函数的结构化验证等。稍后将对圈复杂度和基本圈复杂度做详细介绍。
7.Halsteads Metrics
“Halsteads Metrics”即“Halsteads 度量”,它是一种用于评估软件质量的方法,由Maurice Halstead在1970年代提出,它基于程序中出现的运算符和运算元的数量来进行分析。具体来说,它衡量的是一个程序或模块的复杂性和工作量。在Halstead Metrics中,程序被看作是由运算符和运算元组成的序列。运算符是程序中的动作或操作,如加、减、乘、除等;而运算元则是这些操作的对象,如变量、常量等。通过统计这些元素的出现次数,可以计算出几个重要的指标,如程序容量、工作量、难度等。
testbed的Halsteads 度量包括总操作符、总操作数、独特的操作符、独特的操作数、词汇量、长度、容积等。
8.Loop/Interval Analysis
“Loop/Interval Analysis”即“循环/嵌套分析”,这里按照函数列表的视图进行展示,包括第一个嵌套的个数、最大的嵌套数、可简化的个数(嵌套)、循环的个数、循环嵌套深度等。
9.LCSAJ and Unreachability
“LCSAJ and Unreachability”即“线性代码序列和跳转 和不可达性”,LCSAJ(Linear Code Sequence and Jump)是指一种特定的代码结构,由一组顺序执行的代码段组成,以控制跳转作为结束点。LCSAJ覆盖是一种路径覆盖的变种,它考虑了那些在程序代码里容易表现出来且不需要流图的子路径,这种覆盖方式比判定覆盖更加彻底。LCSAJ是衡量软件质量时考虑的一种代码结构,有助于评估代码的可读性、可维护性和可测试性等方面。通过分析和优化LCSAJ,可以提高软件的质量和性能。
testbed的LCSAJ and Unreachability度量包括LCSAJ 的总个数、不可达的 LCSAJ、 LCSAJ 密度的最大值、不可达代码行数、不可达分支数、可达的 LCSAJ等。
10.Dataflow Information
“Dataflow Information”即“数据流信息”,这里按照函数列表的视图进行展示,包括全局变量个数、扇入数、扇出数等。稍后将对扇入数和扇出数做详细介绍。
二、重点软件质量项详述
1.Cyclomatic Complexity(圈复杂度)
圈复杂度(Cyclomatic Complexity,简称CC)也称为条件复杂度,是一种代码复杂度的衡量标准。这一概念在1976年由Thomas J. McCabe, Sr.提出,用于表示程序的复杂度。圈复杂度是用来衡量一个模块判定结构的复杂程度,数量上表现为线性无关的路径条数,也可以理解为覆盖所有可能情况最少使用的测试用例数。根据经验,程序的可能错误和高的圈复杂度有着很大关系。
圈复杂度是最常用的一种软件质量度量项,各大标准中一般都要求比较苛刻(1 ~ 10),行业实践中一般会稍微放宽到1 ~ 15(仅供参考)。
圈复杂度的计算方法有3种,主要是基于控制流图中的边数、节点数、划分成的区域数等进行计算:
1、公式(一):V(G)=E-N+2(E–表示控制流图中边的数量、N–表示控制流图中节点的数量)
2、公式(二):V(G) = P+1(P–判定节点数)
3、公式(三):V(G) = R(R–平面被控制流图划分成的区域数)
2.Essential Cyclomatic Complexity(基本圈复杂度)
与圈复杂度相关的另一个概念是基本圈复杂度,这是一种衡量程序非结构化程度的度量指标。它基于模块控制流图中的结构化子图的数量来计算,将模块控制流图中的结构化部分简化成节点,计算简化后控制流图的圈复杂度就是基本复杂度。计算公式为EV(G) = V(G) - M,其中V(G)是圈复杂度,M是结构化子图的数量。基本圈复杂度可以帮助我们了解程序模块的结构化程度。
例如,当基本复杂度为1时,这个模块是充分结构化的;当基本复杂度大于1而小于圈复杂度时,这个模块是部分结构化的;当基本复杂度等于圈复杂度时,这个模块是完全非结构化的。
3.Fan in(扇入数)
扇入数(Fan In)是指直接调用一个模块(或函数、过程等)的上级模块的数量。
扇入大意味着模块的复用程度较高,即该模块被多个其他模块调用,表明该模块的功能相对独立和通用。高扇入数通常意味着模块具有较高的聚合性,这有助于提高软件的模块化和可维护性。但是不能为了获得高扇入而不惜代价,例如把彼此无关的功能凑在一起构成一个模块,虽然扇入数高了,但这样的模块内聚程度必然低,这是我们应避免的。
4.Fan Out(扇出数)
扇出数(Fan Out)则是指一个模块直接调用的下级模块(或函数、过程等)的数量。
扇出大意味着模块的复杂度较高,需要控制和协调较多的下级模块。但扇出过小(例如总是为1)也不好,因为这可能表明模块的功能过于单一或缺乏中间层次的抽象。扇出数过大通常是因为缺乏中间层次的模块,此时可以考虑适当增加中间层次的模块来降低复杂度。当扇出数过小时,可以考虑将下级模块进一步分解成若干个子功能模块,或者将其合并到它的上级模块中去。
扇出数一般来说要求为0 ~ 7。
5.代码注释率
从第一章的4、5小结可以看到,testbed对代码注释率的度量做得非常细,具体到了每个源文件、每个函数,甚至区分了函数的头注释、声明注释、可执行代码的注释。但是testbed没有对整个工程进行完整的注释率度量,这个一般也是有要求的(一般要求注释率不低于20%),可以通过SourceCounter、LineCount之类的软件进行统计,如下图所示。
总结
以上就是对Testbed软件质量审查报告中度量项的详细介绍,希望对大家有所帮助,如有疑问可以评论或私信交流。