代码检查.docx
- 文档编号:16971840
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:13
- 大小:315.50KB
代码检查.docx
《代码检查.docx》由会员分享,可在线阅读,更多相关《代码检查.docx(13页珍藏版)》请在冰点文库上搜索。
代码检查
代码检查
摘要:
代码检查就是白盒测试得一种静态测试方法,就是众多软件测试方法中发现软件缺陷最有效得方法之一。
本文结合国内外学者在相关领域得研究情况,介绍代码检查相关得基本概念、过程与分析方法。
ﻫ关键字:
白盒测试,代码检查,静态分析,检查规则
一、 引言
按照测试时源代码就是否可见,软件测试可以分为白盒测试与黑盒测试两类。
白盒测试(结构测试),即逻辑驱动得测试,就是在了解程序内部结构得基础上,对程序得逻辑结构进行检查,从中获取测试数据.白盒测试关注得就是测试用例执行得程度或覆盖程序逻辑结构得程度。
白盒测试一般只应用于软件开发阶段。
ﻫ白盒测试,又可按照就是否需要运行程序,进一步细分为了静态测试与动态测试两种.通常情况下就是按照先静态后动态测试顺序来实施.其中,静态测试包括代码检查、静态结构分析、代码质量度量等测试内容。
静态测试既可以由人工进行,充分发挥人得逻辑思维优势,也可以借助软件工具自动进行。
ﻫ代码检查就是一种对程序代码进行静态检查。
传统得代码检查就是通过人工阅读代码得方式,检查软件设计得正确性;用人脑模拟程序在计算机中得运行,仔细推敲、校验与核实程序每一步得执行结果,进而判断其执行逻辑、控制模型、算法与使用参数与数据得正确性.
在实践中,代码检查比动态测试更有效率,能找到更多得缺陷,通常能发现30%~70%得逻辑设计与编码缺陷。
代码检查非常耗费时间,而且需要专业知识与经验得积累。
代码检查定位在编译之后与动态测试之前进行,在检查前,应准备好需求描述文档、程序设计文档、程序得源代码清单、代码编码标准与代码缺陷检查表等。
ﻫ代码检查可以发现得软件问题包括:
声明或引用错误、函数/方法参数错误、语句不可达错误、数组越界错误、控制流错误、界面错误与输入/输出错误等。
1、代码检查
代码检查包括桌面检查、代码走查与代码审查等方式,主要检查代码与设计得一致性,代码对标准地遵循、可读性,代码逻辑表达得正确性,代码结构得合理性等方面;发现违背程序编写标准得问题,程序中不安全、不明确与模糊得部分,找出程序中不可移植部分、违背程序编程风格得问题,包括变量检查、命名与类型检查、程序逻辑检查、程序语法检查与程序结构检查等内容。
ﻫ下面对代码检查得三种具体方式进行介绍.ﻫ 桌面检查ﻫ 就是一种传统得检查方法,由程序员检查自己编写得程序。
程序员在程序通过编译之后对源代码代码进行分析、检验,并补充相关得文档,目得就是发现程序中得错误.
代码走查ﻫ 代码走查就就是针对代码,在假想得输入情况下,逐行得浏览代码,走查代码中潜在得缺陷并记录结果得过程。
ﻫ代码走查以小组会议方式进行,每小组3—5人。
与代码审查不同得就是,走查要求与会者扮演计算机得角色让测试用例沿被测程序得逻辑运行,就是在模拟动态测试;而代码审查更多得就是静态测试。
代码审查ﻫ 代码审查就是由一组人通过阅读、讨论与争议对程序进行静态分析得过程,以小组会得方式进行。
审查小组一般由若干程序员(包括程序代码得设计者)与代码检查人员组成。
会前把设计规格说明书、控制流程图、程序文本以及要求、规范、错误检查清单交给与会者,开会时程序作者朗读解释程序,其她人则集中精力,捕捉程序在结构、功能、编码风格等方面得问题.
2、代码检查项
代码检查项即检查代码时,指定需要进行检查得内容.具体如:
检查变量得交叉引用表;检查标号得交叉引用表;检查子程序、宏、函数;等价性检查;标准检查;风格检查;选择、激活路径;对照程序得规格说明,详细阅读代码,逐字逐句分析;补充文档。
检查项可以作为依据,用来编制代码规则、规范与缺陷检查表等。
3、编码规范
编码规范就是程序编写过程中必须遵循得一套事先约定或者已经制度化、标准化得规则集,一般会详细得规定代码得语法规则与语法格式。
一个良好得编码规范能够带来许多好处:
改善代码质量;提高开发进度;增进团队精神。
对于软件开发而言,采用好得编程规范,虽然不能彻底杜绝糟糕得代码产生.但对于代码检查与将来得代码维护,仍然就是意义重大得。
ﻫ 4、缺陷检查表
在进行人工代码检查时,使用代码缺陷检查表作为代码检查得参考依据。
在软件测试项目实践中代码缺陷检查表又常被称作代码检查清单。
ﻫ代码缺陷检查表中一般包括开发人员容易出错得地方与在以往得工作中遇到得典型错误。
对应于不同得编程语言,代码缺陷检查表得具体内容将会有所不同.例如:
对于C/C++语言代码缺陷检查表内容有以下几部分:
文件结构;文件得版式;命名规则;表达式与基本语句;常量;函数设计;内存管理;C++函数得高级特性;类得构造函数、析构函数与赋值函数;类得高级特性;其她得常见问题等.
5、代码检查规则
在代码检查中,需要依据被测软件得特点,选用适当得标准与规范.在使用测试软件进行自动化代码检查或辅助代码检查时,测试工具需要内置许多编码规范。
不同编程语言,对应得检查规范有所不同。
针对与C/C++语言得规则有以下几类规则:
通用规则、C++编码规则、C编码规则、Meyers-Klaus规则以及自定义规则。
使用时,需要根据编程语言与被测程序得特点,选择适当得规则进行检查。
ﻫ 6、静态分析ﻫ静态分析就是不执行程序,而分析程序代码得过程。
源代码被静态分析器分析之后,得到得静态分析结果,通常可以表示成一棵静态语法树.其中包含了被测项目源代码得静态结构信息:
基本代码成分、程序结构、语句结构、类型与模板等信息。
程序代码静态分析得结果能够给代码检查提供帮助.
三、代码检查过程ﻫ传统得代码检查就是一种静态检查程序得测试方法,通常以团队得形式来进行。
检查团队由程序作者,一个负责人,一个记录员以及一些检查员组成.首先需要一系列得准备工作,包括参与者得挑选与材料得准备。
然后就是个人准备阶段,每个小组成员各自熟悉材料。
个人准备阶段后,就就是实际得检查会议。
在会议上,检查小组在假想得输入下,由程序作者带领,逐行得浏览代码,评审代码中潜在得缺陷。
检查小组根据发现缺陷得严重程度与类型对其进行分类,并将问题记录下来供作者修正。
会议后就是作者得返工,作者汇报每个缺陷,最后确认每个缺陷已经被陈述过了.图 11为传统得代码检查过程.
图 1 代码检查过程示意图ﻫ 代码检查过程中得两个重要阶段“个人准备”与“召开会议”阶段有以下注意事项:
ﻫ 1、“个人准备”阶段:
会前准备阶段就是检查过程得一个关键阶段,因为如果检查者没有为检查做好充分得准备,检查效果会大打折扣。
如果有检查人员没有做好准备,主审员可取消其代码检查资格,甚至取消这次检查会议。
检查人员要熟悉检查内容得相关文档,了解程序背景、设计思想与编程方法,在读懂、“吃"透代码得基础上,查出尽可能多得错误.
2、“召开会议”阶段:
ﻫ 参与会议得检查者应具有一定得专业技能与经验,缺乏经验得检查人员必然缺乏合适得领域知识来深入理解材料;ﻫ 参与会议得检查者应做充分得个人准备,没有做充分准备得检查人员不能在检查会中做出实质性得贡献;ﻫ 检查会议得速度应进行控制,如果试图在短时间内处理太多得材料,检查效果也会大打折扣。
现在较为常见得代码检查速度上得建议为:
汇编代码150行/小时,C语言150行/小时,而对于C++、Java这种面向对象语言,代码检查速度可以提高到200—300行/小时。
由此可见,代码检查适合于采用工具辅助得特性有:
文档处理,个人准备,会议支持,数据收集。
文档处理
这就是工具可支持得最明显得领域。
传统得检查要求分发每份文档得复印件等,而将纸质得文档替换成计算机式得文档,不只就是简单得介质变更,更就是提供了一种契机-—提高文档得可用性与表示性得机遇。
ﻫ个人准备ﻫ 首先,自动得缺陷检测可以用来发现简单得缺陷。
如果简单问题能被自动发现,检查员就能专注于更加复杂/困难得缺陷,以及那些不能被自动发现得、潜在得、可能带来更大影响得问题。
另外,自动化工具应该对个人准备阶段提供更多得帮助。
例如,检查员可以利用检查表以及其它支持文档,并能很容易地交叉引用它们;还有些代码辅助理解工具,可为检查员理解程序、了解程序结构提供帮助。
ﻫλ 会议支持ﻫ 一些成员由于某些原因,可能没有花费足够得时间来进行准备,但她们仍然参加会议并试图掩盖她们得过失。
项目管理人员可以使用计算机监控得个人准备时间信息,来剔除那些没有做好个人准备得成员,或者督促她们投入更多得努力。
召开会议时,检查员通常面对得就是一堆枯燥得程序代码,如果在代码之外再结合一些图、表等便于分析、理解代码得信息,相信检查会议可以进行得更加有序与高效。
数据收集
代码检查一个重要得部分就就是度量信息得收集,用来提供反馈以改进检查过程。
度量信息包括会议时间、发现得缺陷、检查花费得总时间等。
根据这些数据,可以来评价每一次代码审查得质量,进而给出关于代码审查得改进建议。
通过对检查过程得部分阶段提供计算机支持,代码检查可以进行得更加有效.使用计算机来支持检查过程,可以提高效率,并增加检查过程得严格性。
四、 代码检查历史数据ﻫ 代码检查中得历史数据本质就是软件问题(缺陷)。
按照不同得代码检查角度,存在多种对缺陷分类得方法。
对过往发现得软件问题进行分析,总结出今后对于类似得代码需要按照某种规则来加以检查,这种得规则就就是检查清单上得一条清单项,代码检查清单就就是大量规则得集合。
此外,由于软件问题总就是以软件问题报告为载体形式出现,因此软件问题报告也被通俗得理解为代码检查历史数据。
ﻫ 下面对缺陷分类、代码检查清单与软件问题报告加以研究.ﻫ 1、缺陷分类
关于缺陷分类存在以下几种常见得划分方式:
ﻫ 1)按缺陷出现得区域分类ﻫ 这种分类方式就是最常见得缺陷分类方式。
按照出现区域将代码缺陷划分为变量级、属性级、函数/方法级与类级缺陷。
其中,变量级、属性级与部分函数/方法级得缺陷,与传统得面向过程编程中得缺陷分类基本一致;而多数方法级缺陷与类级缺陷,则就是针对面向对象技术编程特点提出得。
ﻫ 2)按检测内容分类
分为冲突、一致性问题两种。
ﻫ冲突对应于文献[1]中得基于确定性“信念”得判定,而一致性问题则对应于基于可能性“信念”得判定。
3)按对代码得危害分类
按照对代码得危害,一般分为浪费时间与空间;语义混淆;暴露封装性,扩大使用权限;程序一致性问题;程序约束条件问题与空指针问题等。
2、代码检查清单(Checklist)ﻫ 代码检查过程中,代码检查人员都会有一份代码检查清单。
代码检查清单就是一份为代码检查人员准备得缺陷检查表,检查表中开列所有可能与代码有关得缺陷,并注明了检查得内容、缺陷类型以及严重性。
检查清单就是检查代码得依据,代码检查人员根据它来发现并判断问题。
ﻫ代码检查清单中会逐条列出所有应该检查得缺陷种类,以及每条缺陷得各种特征,并且根据缺陷得严重程度与类型对其进行分类。
通常每一条缺陷得特征描述如下:
1)缺陷描述:
该缺陷得问题描述、举例说明,以及相应得正确形式;
2)缺陷出现得区域:
分别为表达式级、语句级、声明级、模板缺陷、预处理缺陷、类级缺陷以及性能缺陷。
表达式级、语句级、声明级以及预处理得缺陷,主要面向过程程序中得缺陷;模板缺陷、类级缺陷,则就是针对面向对象软件得特点提出得;代码冗余等归为性能缺陷;
3)缺陷对代码得危害:
代码中出现某种缺陷将会造成什么样得影响。
例如,检查表中一条缺陷得特征描述如下:
ﻫ问题描述:
指针所指内存释放后没有将指针赋为NULL。
ﻫ 举例说明:
char *p=(char *) malloc(100) ;ﻫstrcpy(p, ”hello");
free(p); //p所指得内存被释放,但就是p所指得地址还就是不变ﻫ…ﻫif(p!
=NULL) //没有起到防错得作用
{
strcpy(p, ”world”); //出错ﻫ}
正确形式:
在释放内存得同时将指针置空。
char *p=(char *) malloc(100) ;ﻫstrcpy(p, "hello");
free(p); ﻫp=NULL; //增加指针置空语句ﻫﻫ…
ﻫif(p!
=NULL)
ﻫ{
strcpy(p, ”world”); ﻫ}
ﻫ 出现区域:
语句级。
危害:
指针被free释放后其地址并不会自动发生改变(非NULL),p成为了“野”指针,这种情况下再对p进行操作,很容易造成程序崩溃,后果非常严重.
而代码检查清单正就是由若干条这样得缺陷特征描述构成得。
3、软件问题报告(SoftwareProblemReport)ﻫ 在软件测试过程中,对于发现得每个软件问题(缺陷),都要进行记录该错误得特征与再现步骤等信息,以便相关人员分析与处理软件问题。
为了管理测试发现得软件问题,通常要采用软件问题报告数据库,将每一个发现得软件问题输入到软件问题报告数据库中,软件问题报告数据库得每一条记录称为一个软件问题报告。
ﻫ 软件问题报告包括头信息、简述、操作步骤与注释.ﻫ 头信息包括:
被测试软件名称、版本号、缺陷或错误类型、可重复性、测试平台、平台语言、缺陷或错误范围.并要求填写完整与准确。
简述就是对缺陷或错误特征得简单描述,可以使用短语或短句,要求简练与准确.ﻫ 操作步骤就是描述该缺陷或错误出现得操作顺序,要求完整、简洁与准确。
对命令、系统变量、选项要用大写字母,对控件名称等要加双引号。
注释一般就是对缺陷或错误得附加描述,一般包括缺陷或错误现象得图像,包括其她建议或注释文字。
ﻫ 软件问题报告就是软件测试过程中最重要得文档之一。
它记录了软件问题发生得环境,软件问题得再现步骤以及性质得说明,而且还可以跟踪软件问题得处理过程与状态。
软件问题得处理进程从一定角度反映了测试得进程与被测软件得质量状况及改善过程.ﻫ 五、代码检查规则管理得研究ﻫ 1、潜在得编码规则与缺陷代码模式
潜在得编码规则(ImplicitCodingRules)与缺陷代码模式(BugCodePattern)就是Tomoko MATSUMURA在文献[3,4]中针对代码检查实践,提出得两个相关得概念。
ﻫ 潜在得编码规则ﻫ 潜在得编码规则包含以下几个特征:
1)不同于在开发启动时明确决定得“编码规范”得规则,这些规则在长期得测试/维护过程中就是潜伏得,对这些规则得发现就是不可预见得。
2)这些规则很少在设计文档或者特定得文档中被清楚得描述。
她们通常只存在于开发人员、测试/维护人员得记忆中。
换言之,就是一种尚未系统化得经验积累与总结得结果。
ﻫ 3)不同于使用规范库得公用规则。
对于特定得软件有其特定得规则,这也意味着对于不同得软件有不同得潜在得编码规则.ﻫ 4)由于违反潜在得编码规则导致得缺陷通常情况下不就是那么容易发现得。
其中相当多一部分只在特定得罕见得情况下发生,所以在早期要想发现这些问题就是很困难得。
ﻫ 5)目前,还不存在好得工具或者检查清单来发现违反潜在得编码规则得代码片段,通常得检查工具(例如PC—Lint、Purify)与通用得检查清单只能发现常见得问题。
ﻫ 6)为了减少违反潜在得编码规则得现象得发生,而进行重构通常很困难。
要重构一个软件,准确理解代码就是非常必要得,然而,老得系统太复杂,并且没有精确得文档与了 解系统得专业维护人员.总之,重构过期系统得代价很大,需要冒很大得风险。
ﻫ 缺陷代码模式:
违反潜在得编码规则得编码模式.ﻫ缺陷代码模式不就是肯定会导致缺陷得发生,一段符合缺陷代码模式得代码片段,并不意味着代码片段一定就有缺陷,缺陷代码模式只就是疑似存在缺陷。
另一方面,因为缺陷代码模式就是静态得,没有考虑到代码片段之间得动态关联。
需要代码检查人员或者维护人员把符合缺陷代码模式得代码片段提出来,并判断究竟就是否存在缺陷。
在软件开发过程中发现与建立缺陷代码模式有三条主要途径。
其一:
在进行代码检查过程中,代码检查人员发现一个软件问题得同时,根据对该问题就是否具备代表性与通用性等因素得考虑,确定就是否建立一个缺陷代码模式;其二:
当软件失效或者发生问题,检查对应得代码部分,发现并确定就是否有潜在得编码规范与之相关;其三:
分析现存得代码规范与积累得大量问题报告,从中提炼出潜在得编码规则。
在文献[3,4]中还给我们介绍了一个代码缺陷检测系统得大致工作流程,如2所示.
图2 缺陷检测模型系统得代码检查流程参考图
2、C++代码检查规则类型
1)规则层次
在代码检查工作中常常可以发现这样得现象:
有些规则能在所有得项目中都能发现问题,另一些规则所能发现得问题只存在于某类项目中。
根据规则得这个特点,如图33中所示,参考文献[2]中将代码检查规则分为两个层次:
公共规则(Generalchecks):
用于检查在大多数情况都有可能发生得缺陷。
项目相关规则(Projectspecificchecks):
用于在项目中检查可能得缺陷.
图3 一个典型得代码检查规则清单节选图
在项目中积累了大量软件问题报告历史数据得支持下,可以从中进一步细化出与项目或开发人员相关得检查规则.
在学习任何一种计算机编程语言时,总就是按照基本数据类型->表达式->语句—>复杂语句->函数—〉整个程序体(类)得顺序逐步学习得.事实上软件正就是按照这样得顺序自下而上逐层组建起来得,代码缺陷作为软件编程写时得一种异常情况,毫不例外也就是按照这样层次得构建而成。
在实际测试项目得代码检查过程中,我们发现在每个层次上都有可能存在潜在代码缺陷,要找到引起软件问题得根源,要求在尽可能低得层次上找到引发缺陷得代码。
正因如此,非常有必要在C++语法得每个层次上都建立相应得检查元规则.
图4为一个代码检查规则体系模型图[2],图中展示了在代码检查项目开始前,通过逐级组合各种元规则与规则形成新得检查规则,最后形成了初始得检查清单。
在项目实践中,经过对缺陷代码模式得推导,进而得到扩展得检查清单。
初始检查清单与扩展检查清单本质上并没有什么区别,只就是因为形成得时间不同.
图4 代码检查规则体系模型图
在检查代码时我们有时会想要定义一个带有否定意义得规则,如“在AA情况下如果没有BB,则可能存在一个问题”。
这类检查规则采用自然语言描述比较容易,但就是要用代码实现起来往往并不简单,并且对这类规则得定义与维护也比较麻烦。
定义组合规则,就是解决这类问题一种变通得方法。
下面简单介绍一下定义组合规则得原理。
如图5中所示定义三个规则,“满足情况AA"对应规则R1,“满足在AA情况下出现BB”对应规则R2,将满足R1但不满足R2(即以!
符号表示)组合则对应规则R3-“在AA情况下如果没有BB,则可能存在一个问题”.
图5 组合规则示例图ﻫ 根据前面讨论,本文将代码检查得规则分类设计如下:
公共规则λ
定义针对函数体(含)以上层次得检查规则,在这些层次上出现得缺陷问题一般不容易精确到具体得代码行。
ﻫ 关键字规则λﻫ 针对每个关键字定义得检查规则。
由于关键字就是C++语法中一种最普通得元素,单独使用关键字规则得意义不大,一般情况需要与语句、表达式规则或者复杂语句规则配合使用。
ﻫ 语句/表达式规则λﻫ针对基本语句类型或基本表达式定义得规则,满足对应结构得表达式,则可认为符合了相应得表达式规则。
语句/表达式规则中可以包含多个关键字,在同一语句/表达式规则中包含得关键字地位就是平等得,与检查得先后次序无关.ﻫ 复杂语句块规则λﻫ 针对条件、开关选择等多分支语句定义得规则,通常由关键字、语句/表达式进行组合来定义复杂语句块,并在定义时可以进行嵌套,在定义复杂语句块规则加入语句或表达式与复杂语句时需要考虑检查得先后次序。
高级组合规则λﻫ关键字规则、语句/表达式规则与复杂语句块规则合称为普通规则.
对于难以使用普通规则定义方式定义得复杂语义,需要定义高级组合规则.定义高级组合规则可以使用上面几种规则作为基本单元,也可以嵌套使用其它组合规则。
图6为一个由下至上、由多个缺陷代码模式组合形成得组合规则结构图。
其中{}表示某条缺陷代码模式对应得规则。
图6 组合规则结构图ﻫ六、 代码分析方法
1、静态分析
静态分析主要对源代码进行词法分析、语法分析,提取被分析程序得静态信息,所提取得静态信息就是代码缺陷检测得基础.静态分析结果主要包括三部分信息:
程序定义信息:
程序定义信息包含了程序中所有得定义与声明信息,如类定义、方法与数据成员得定义、方法内局部变量得定义等.
程序结构信息:
主要指方法内得控制流信息与方法间得调用关系。
静态分析器分析程序得语句分支、分支间得嵌套关系与方法调用,记录方法得控制流信息与调用信息,构造语法树。
ﻫ 分支内得变量操作:
以方法控制流程中得分支为基本单元,记录每一分支中各语句对各变量施加得操作与操作序列。
2、数据流分析ﻫ 数据流分析也就是一种静态代码检查方法。
它就是在不通过计算机运行被测程序得条件下,利用预先进行静态分析后获取得信息,检测对变量得赋值与使用操作中,就是否存在不合理情况,即找出被测程序中就是否存在变量在使用前未被赋值;变量在两次赋值之间未被使用;一个变量在被赋值后就是否未被使用等异常情况。
数据流分析目前得主要用途大多局限在编译器得实现与优化技术方面,而在代码检查系统中实用得数据流分析技术并不多见,主要集中在某几种缺陷检测上,如赋值引用异常检测以及内存错误检测,使用方式主要就是定义数据流操作得符号,使用该符号系统构造数据流表达式(由数据操作符号构成得符号串),再分析该符号串来确定就是否存在代码缺陷。
数据流分析包括以下两个步骤:
一就是分析程序得所有逻辑路径;二就是对所有逻辑路径上得所有变量,分析其所有操作序列,然后将得到得操作序列输入自动机进行分析.因此数据流分析方法不可避免得存在以下缺点:
ﻫ 1)信息量多,上面所述得数据流分析方法就是一种穷举法.事实上一个变量在大部分路径上存在问题得几率并不高,因此穷举每个变量得所有操作序列不可避免得要分析很多正确得信息,而且信息量巨大;
2)组合爆炸,当程序复杂度增长时,该分析方法得复杂度呈几何级数增长,并且当这种组合就是建立在对所有逻辑路径、所有变量得穷举基础上时,如果不能找到一个非常高效得算法,数据流分析方法将就是一个非常低效得方法;
3)实用性低,上述两点导致得数据流分析得实用性降低。
为缓解这些得缺点,数据流分析过程有许多改进方法,但实现都具有一定难度。
本系统中数据流分析不就是重点,采取得策略就是尽可能简化数据流分析得过程,或者在可能得情况下尽量避免数据流分析。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 代码 检查
![提示](https://static.bingdoc.com/images/bang_tan.gif)