友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

软件测试的艺术(中文清晰版)(PDF格式)-第8章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






责该代码的程序员本人)会建议对设计进行明显的修补以解决这个特例。那么,对 



这个小问题的讨论,反过来会将整个小组的注意力集中在设计的某个部分。在探讨 



修补设计来解决这个小问题的最佳方法时,有人可能会注意到另外的问题。既然小 



组已经发现了设计中同一部分的两个相关问题,那么每隔几段代码就可能需要密集 



的注释。几分钟之内,整个设计就被彻底检查完,任何问题都会一目了然。 



  在代码检查的时间及地点的选择上,应避免所有的外部干扰。代码检查会议 



的理想时间应在90~120分钟。由于开会是一项繁重的脑力劳动,会议时间越长效 


…………………………………………………………Page 31……………………………………………………………

                        第3章 代码检查、走查与评审  19 



率越低。大多数的代码检查都是按每小时大约阅读150行代码的速度进行。因此, 



对大型软件的检查应安排多个代码检查会议同时进行,每个代码检查会议处理一 



个或几个模块或子程序。 



3。2。3   对事不对人,和人有关的注意事项 



  请注意,要使检查过程有成效,必须树立正确的态度。如果程序员将代码检 



查视为对其人格的攻击、采取了防范的态度,那么检查过程就不会有效果。正确 



的做法是,程序员必须怀着非自我本位的态度来对待检查过程,对整个过程采取 



积极和建设性的态度:代码检查的目标是发现程序中的错误,从而改进软件的质 



量。正因为这个原因,大多数人建议应对代码检查的结果进行保密,仅限于参与 



者范围内部。尤其是如果管理人员想利用代码检查的结果,那么就与检查过程的 



目的背道而驰了。 



3。2。4   代码检查的衍生功效 



  除了可以发现错误这个主要作用之外,代码检查还有其他的衍生作用。其 



一,程序员通常会得到编程风格、算法选择及编程技术等方面的反馈信息。其 



二,其他参与者也可以通过接触程序员的错误和编程风格而同样受益匪浅。通 



常来说,这种类型的测试方法能够增强项目中团队的凝聚力,减少消极人际关 



系滋长的可能性,有利于打造高度合作的、高效的以及信得过的开发模式。 



(要辩证看待码检查的这些功效,一旦没有做好出现像前面提到的人身攻击之 



类的事情,则造成恶劣影响,所以进行代码检查一定要准备充分且不断摸索成 



功经验,摈弃不好的实践。—译者注) 



  最后还有,代码检查是能够在早期发现程序中脆弱部位的方法之一,有助 



于在测试过程中将更多的注意力集中在这些脆弱地方(与第2章第9条测试原则 



不谋而合)。 



3。3   用于代码检查的错误列表 



  代码检查过程的一个重要部分就是对照一份错误列表,来检查程序是否存在 



常见错误。遗憾的是,有些错误列表更多地注重编程风格而不是错误(例如,“注 



释是否准确且有意义?”,“if…else代码段和do…while代码段是否缩进对 


…………………………………………………………Page 32……………………………………………………………

20  软件测试的艺术 



齐?”),错误检查太过模糊而实际上没有用(例如,“代码是否满足设计需求?”)。 



本节中讨论的错误列表是经多年对软件错误的研究编辑而成的。该错误列表在很 



大程度上是独立于编程语言的,也就是说,大多数的错误都可能出现在用任意语 



言编写的程序中。读者可以把自己使用的编程语言中特有的错误,以及代码检查 



发现的错误补充到这份错误列表中去。 



3。3。1   数据引用错误 



   1。 是否有引用的变量未赋值或未初始化?这可能是最常见的编程错误,在各 



    种环境中都可能发生。在引用每个数据项(如变量、数组元素、结构中的 



    域)时,应试图非正式地“证明”该数据项在当前位置具有确定的值。 



  2。 对于所有的数组引用,是否每一个下标的值都在相应维规定的界限之内? 



  3。 对于所有的数组引用,是否每一个下标的值都是整数?虽然在某些语言中 



    这不是错误,但这样做是危险的。 



  4。 对于所有的通过指针或引用变量的引用,当前引用的内存单元是否分配? 



    这就是所谓的“虚调用”(dangling  reference )错误。当指针的生命期大于 



    所引用内存单元的生命期时,错误就会发生。当指针引用了过程中的一个 



    局部变量,而指针的值又被赋给一个输出参数或一个全局变量,过程返回 



    (释放了引用的内存单元)结束,尔后程序试图使用指针的值时,这种错误 



    就会发生。与前面检查错误的方法类似,应试图非正式地“证明”,对于每 



    个使用指针值的引用,引用的内存单元都存在。 



  5。 如果一个内存区域具有不同属性的别名,当通过别名进行引用时,内存区 



    域中的数据值是否具有正确的属性?在FORTRAN语言中对EQUIVALENCE 



    语句使用,或COBOL语言中对REDEFINES语句使用的地方,都可能发生 



    这种错误。例如,一个FORTRAN语言程序包含一个实型变量A和一个整型 



    变量B ,两者都通过使用EQUIVALENCE语句而成为同一内存区域的别名。 



    如果程序先对A赋值,然后又引用变量B ,由于机器可能会将内存中用浮点 



    位表示的实数当做整数,在这种情况下错误就可能发生。 



  6。 变量值的类型或属性是否与编译器所预期的一致?当C 、C++或COBOL程 



    序将某个记录读到内存中,并使用一个结构来引用它时,由于记录的物理 



    表示与结构定义存在差异,这种情况下错误就可能发生。 


…………………………………………………………Page 33……………………………………………………………

                        第3章 代码检查、走查与评审    21 



            COBOL与Fortran背景资料 



   COBOL和Fortran是两门分别面向商业处理和科学计算开发方向的 



元老级别的编程语言,这两门语言为数代的程序员提高开发效率作出 



了不可估量的贡献。 



   COBOL (取自mon  Business  Oriented  Language 的粗体部分) 



的雏形诞生于1959年前后,其设计的主要目的是为了支撑大型机系统 



上的商业应用软件的开发工作,其最初的规格设计可谓是集众家之长, 



当时参与COBOL 项目的有知名的计算机制造商以及联邦政府机关, 



他们共同创造了一门全新的、面向商业的、能够运行在各种硬件和操 



作系统之上的编程语言。 



   这些年来,C O B O L 语言标准不断完善和发展。到2 0 0 2 年, 



COBOL几乎能够在大多数的操作系统平台进行开发和运行,甚至还 



推出了一个用来集成开发环境的面向对象版本。 



   到本书写作之际,目前最新版本的COBOL是Visual COBOL 2010 。 



   Fortran (最早拼写成FORTRAN ,不过现在更倾向于首字母大写 



的规范)的诞生比COBOL还要稍微早点,其规格定义最早可以追溯 



到20世纪50年代早中期。和COBOL类似,Fortran被设计用来针对某 



些特殊类型(尤其是科学和数字计算方面)的大型机应用系统开发。 



Fortran 这个名字来源于当时IBM 一个叫做Mathematical  FORmula 



TRANslating  System (名字取自字体加粗部分)的系统。虽然最初的 



Fortran 只有32种语句,但是这已经远远超越了当时的汇编程序设计语 



言,是具有划时代意义的进步。 



   到本书出版之际,最新的Fortran版本是Fortran  2008 ,已经在2010 



年被标准委员会正式通过。和COBOL一样,Fortran语言的演进伴随着 



对更多硬件和操作系统的支持,不过有一点不同的是,不管是现有系 



统的开发还是老系统的维护,Fortran都可能比COBOL应用得更广泛。 



7。 在使用的计算机上,当内存分配的单元小于内存可寻址的单元大小时,是 



 否存在直接或间接的寻址错误?例如,在某些条件下,定长的位串不必以 


…………………………………………………………Page 34……………………………………………………………

22  软件测试的艺术 



    字节边界为起点,但是地址又总是指向字节边界的。如果程序计算一个位 



    串的地址,稍后又通过该地址引用这个位串,可能会指向错误的内存位置。 



    将一个位串参数传送给一个子程序时,也可能发生这种情况。 



  8。 当使用指针或引用变量时,被引用的内存的属性是否与编译器所预期的一 



    致?这种错误的一个例子是,当一个指向某个数据结构的C++指针,被赋 



    值为另外的数据结构的地址。 



  9。 假如一个数据结构在多个过程或子程序中被引用,那么每个过程或子程序 



    对该结构的定义是否都相同? 



  10。 如果字符串有索引,当对数组进行索引操作或下标引用,字符串的边界取 



    值是否有“仅差一个”(off…by…one )的错误? 



  11。 对于面向对象的语言,是否所有的继承需求都在实现类中得到了满足? 



3。3。2   数据声明错误 



  1。 是否所有的变量都进行了明确的声明?虽然没有明确声明不一定是错误, 



    但通常却是麻烦的源头。举例来说,如果一个程序的子程序接收一个数组 



    参数,却未将该参数定义为数组(如用 DIMENSION  语句),对该数组的 



    引用(如 C=A  (I) )会被解释为一个函数调用,导致计算机试图将此数组 



    当做程序执行。另外,如果某个变量在一个内部过程或程序块中没有明确 



    声明,是否可以理解为该变量在这个程序块中被共用? 



  2。 如果变量所有的属性在声明中没有明确说明,那么默认的属性能否被正确 



    理解?举例来说,在Java语言中,程序接收到的没有正确声明的默认属性 



    往往是导致意外情况发生的源头。 



  3。 如果变量在声明语句中被初始化,那么它的初始化是否正确?在很多语言 



    中,数组和字符串的初始化比较复杂,因此也成为容易出错的地方。 



  4。 是否每个变量都被赋予了正确的长度和数据类型? 



  5。 变量的初始化是否与其存储空间的类型一
返回目录 上一页 下一页 回到顶部 1 1
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!