1、问题定义,编 码,需求分析,总体设计,可行性研究,维 护,测 试,开发 时期,维护 时期,定义时期,(目标与范围说明书),(可行性研究报告),(维护报告),(测试报告),(程序),(总体设计文档),(需求规格说明书),详细设计,(详细设计文档),第7章 实现,7.1 编码 7.2 软件测试基础 7.3 单元测试 7.4 集成测试 7.5 确认测试 7.6 白盒测试技术 7.7 黑盒测试技术 7.8 调试 7.9 软件可靠性,通常把编码和测试统称为实现。 编码:把详细设计结果翻译成用某种程序语言书写的程序。 软件测试:是保证软件质量的关键步骤,它是对软件规格说明、设计和编码的最后复审。 软件测试
2、分2个阶段: 编码与单元测试:编写一个模块,对它做测试,编写者和测试者同一个人。 综合测试:编码与单元测试结束后,进行的集成测试,是一个独立阶段,由专门的测试人员进行测试。 测试的目标:是发现软件中的错误; 调试的目的:是通过测试发现错误后,诊断和改正错误。,高级语言明显优于汇编语言。因此: 1)除了很特殊的应用领域 对程序执行时间和使用空间都有很严格限制的情况; 需要产生任意的,甚至非法的指令序列;(高级语言没有此功能) 体系结构很特殊的微处理机(不能使用高级语言); 2)大型系统中执行时间非常关键的(或直接依赖于硬件的)一小部分代码。需要用汇编语言书写外, 其他程序一律用高级语言书写。,7
3、.1 编码 7.1.1 选择程序设计语言,选择高级语言的标准 1理想标准 1)有理想的模块化机制,以及可读性好的控制结构和数据结构; 2)编译程序能够尽可能多地发现程序中的错误; 3)有良好的独立编译机制。(编写一个模块就能编译)。,2实用标准 1)系统用户的要求 如果系统由用户负责维护,用户希望用他们熟悉的语言写程序。 (会JAVA,而不会C#;会WINDOWS系列,而不会LINUX) 2)可以使用的编译程序?(好坏) 3)可以得到的软件工具(多少) 4)工程规模(大小) 5)程序员的知识,采用程序员所熟悉的语言。JAVA,6)软件可移植性要求。 系统用各种不同的计算机或寿命很长,应选择标准
4、化程度高、可移植性好的语言。 /* 应该选择未来一定时间内占主导地位的语言 (FOXPRO,ORACLE)邮电管理系统 7)软件的应用领域。 其中软件的应用领域是最关键的因素。各种语言往往使用于不同的应用领域。,7.1.2 编码风格,风格:书写源程序的习惯,程序代码的逻辑结构,习惯的编程技术。(习惯的变量命名方法)程序读者有2个(机器和人),强调风格主要针对于人的可读性,可理解性。源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准。为了做到这一点,应该遵循下述原则。,1程序内部的文档 包括标识符、适当的注解、程序的视觉组织。 标识符:包括模块名、函数名、变量名、常量名、子程序名等。 1)
5、变量名的选择 (1) 采用有实际意义的变量名 有实际意义的名字能帮助理解和记忆; 例如:TotalSum空格总数,Sum每行空格数目 可以把D=S*T写成,DISTANCE=SPEED*TIME(见名知意) 变量名一般情况下取412个字符为宜; 最好事先能对变量名的选择约定统一的标准,以后阅读就会方便。这一技巧对过程名、函数名、类名、对象名等同样适用。,(2)变量和函数的常用命名方法 下划线法(在每一个英文单词前,加下划线) 在变量名和函数中使用下划线是一种风格,会大大加强可读性total_sum, print_report() 骆驼式命名法(每一个单词的第一个字母写大写) 混合使用大小写字母
6、来构成变量和函数的名字TotalSum, PrintReport() 函数的命名采用动词/名词结构ExitSystem(), 匈牙利式命名法(数据类型+骆驼式方法) MS公司的程序员 Charles Simonyi(匈牙利人的后裔)提出。 结构:数据类型+骆驼式 变量名或函数名前要加上,一个或两个字符的前缀,用来表示变量或函数的数据类型;后部分用骆驼式命名法。 MS Windows ,Visual Basic ,Office等大量使用了匈牙利命名法或其变体。,匈牙利式命名法(数据类型+骆驼式方法)例子,(3)不用过于相似的变量名 因为这样容易引起误解和打字错误。 例如:ELL、EMM、ENN、
7、EMMN、ENNN等 放在一起很容易混淆, 又如:POSITIONX和POSITIONY是仅仅末尾不相同的长标识符,如果编译程序只识别前8个字符就会出现错误,所以不安全。,(4)变量名中一般不要带有数字 字母:O、I(l)、Z、S 数字: 0、1、 2、5 ,极易混淆(5)同一变量名不要有多种含义 例如变量NEW在程序的第一、第三、第四段 分别表示不同的含义,则阅读时容易误解, 将来修改时也会造成错误。,(6)显式地声明一切变量int a,b,c;float x,y,z;(7)对变量最好作出注释说明其含义int sum; /*sum:统计每行空格数*/int total_sum; /* tot
8、al_sum :统计空格总数*/,2)程序的注解 在正规的程序文件中, 注解行的数量占整个源程序的1/5到1/3,甚至更多。 只有代码,没有注解的程序是不可取的。(1)序言性注解 序言性注解通常位于每个程序模块的开头部分, 它应当给出该模块的整体说明, 模块名称、功能、主要算法、接口特点、 重要数据、开发简史。, Main() ,(2)功能性注解 功能性注解应插入在源程序体中,用以描述其后的语句是在做什么工作,主要解释包含这段代码的必要性和提供一些额外的信息。 TotalSum= TotalSum +Sum /* 把每行的空格数累加到总空格数中*/ 应该用空格和空行清楚地区分注解和程序。注解的
9、内容一定要正确,是最新式的。 (程序修改后,必须修改注解),3)视觉组织 空格、空行和缩进(阶梯式)。FOR i=1 TO mFOR j=1 TO nP=i*jENDFORENDFOR 颜色:关键字,注解FOR i=1 TO m /*循环,2数据说明 1)数据说明的次序应当规范化 原则上,数据说明的次序与语法无关,其次序是任意的。 但出于阅读、理解和维护的需要最好使其规范化,使说明的先后次序固定。 例如,常量说明、类型说明、全程量说明、局部量说明。 在类型说明中还可按如下顺序排列: 整型量实型量字符量逻辑量说明,2)当多个变量名用一个语句说明时,按字母排列。int size, length,
10、width, cost, total; /* 尺寸、长度、宽度、价格、总计 */ 写成, int cost, length, size, total, width ; 3)如果设计了一个复杂数据结构,应使用注释说明这个数据结构的特点。如;C链表结构和PASCAL中用户自定义的数据类型,应在注释中说明。,3. 语句构造 1) 程序结构清晰,简单易懂单个函数的程序行数不得超过100行。(一个模块) 2) 在一行内只写一条语句 3) 尽量使用标准库函数和公共函数;include ,#define PI 3.1415926; 4) 使用括号使逻辑表达式或算术表达式的运算次序清晰直观 5)尽量使用局部变
11、量,不要随意定义全局变量(耦合度增加) 6) 避免大量使用循环、分支嵌套循环、分支嵌套层数不要超过3-4层,IF X=0 THENIF X0 THENY=1ELSEY=0ENDIF ELSEY=-1 ENDIF,7) 尽量避免复杂的条件测试 8) 保持注解与程序代码完全一致 9) 注解行数应占总行数的1/5到1/3 10) 禁止使用GOTO语句,(检测出错误时才使用GOTO语句) 11) 所有变量使用前必须进行初始化 12) 不要比较浮点数的相等,如:10.0*0.1=1.0,不可靠或通常等式不成立。 13) 编译程序只能检查语法错误,不能检查逻辑或算法错误。 14) 经常反省“别人能看懂我的
12、程序吗?”,测试和维护也许是别人进行。,4输入输出 输入和输出的格式应当尽可能方便用户的使用,对用户友善。 系统能否为用户接受,有时就取决于输入和输出风格。 (用户界面、输出报表格式) 在设计和编写程序时应该考虑几个规则: 1)对所有输入数据都进行检验,识别错误的输入,保证每个数据的有效性。例如:身份证号码18位,少了有提示,多了有警告。 2)检查输入项重要组合的合法性ax2+bx+c=0, b2-4ac=0(无虚根)如,三角形,两边之和必大于另一边长,如有问题则拒绝接收。a+bc, a+cb, b+ca,3)保持输入格式简单并输入的步骤和操作尽可能简单。输入结束请确认。 4)向用户显示“请输
13、入”等的提示信息,同时说明允许的选择范围和边界数值。 5)设计良好的输出报表。 6)对所有的输出数据加标志。车票销售了要加标记(3车,50号),5效率 效率主要指处理机(CPU)时间和存储器容量。 程序效率三原则: 1)效率是一种性能要求。目标值应当在需求分析阶段给出。根据实际需要来要求效率,不是越高越好。 (数据精度、时间特性响应时间、更新处理时间、运行时间、适应性) 2)效率是靠良好的设计来提高。 3)程序的效率和程序的简单程度是一致的。THE SIMPLE IS THE BEST, 越简单,越好不要牺牲程序的可读性或可靠性来提高效率, 这样会给以后的维护工作带来严重困难。,从三个方面讨论
14、效率问题 程序运行时间(算法对效率的影响)程序的效率与算法的效率、写程序的风格有关。 存储器效率或内存效率提高存储器效率主要是:指如何使存储量大,占用存储单元少,存取时间短。 输入/输出效率,一、测试的重要性 软件测试是保证软件质量的关键步骤, 是对软件规格说明、设计和编码的最后复审。 软件测试的工作量占总开发工作量的40%以上。按照Boehm的统计, 软件测试的开销大约占总成本的30%-50%。 例如:APPOLLO登月计划,80%的经费用于软件测试。,7.2 软件测试基础,二、测试的必要性 1在软件生命周期的每个阶段都会产生错误; 2每个阶段结束后进行技术审查,以发现和纠正错误。但是经验表
15、明技术审查并不能发现所有错误; 3在编码过程中还可能引入新的错误。 所以软件投入生产性运行之前进行测试, 尽可能多地发现和改正软件中的错误。,1963年美国飞往火星的火箭爆炸,造成1000万美元的损失。原因是FORTRAN程序:DO 5 I=1,3 误写为:DO 5 I=1 . 3,1967年苏联“联盟一号”载人宇宙飞船在返航时,由于软件忽略一个小数点,在进入大气层时因打不开降落伞而烧毁。,三、不完整测试的危害性 任何微小的错误所引起的后果都将是十分严重的。 例如:,这个例子告诉人们,不彻底的测试所发生的错误,有多么严重的后果,Back,四、神舟六号载人航天介绍神舟六号2005年10月12日9
16、时0分, 从酒泉卫星发射中心发射升空 。 17日4时33分,神舟六号飞船着陆。神舟六号由火箭和飞船两大部分组成。,火箭全长58.3米,起飞重量479.8吨, 由4个液体火箭助推器和芯一级、二级、整流罩、逃逸塔组成, 包括控制系统、故障检测系统、遥测系统、外测安全系统、逃逸系统、箭体结构、动力系统、推进剂利用系统、 附加系统和地面设备等10个分系统。飞船由推进舱、返回舱、轨道舱的三舱结构组成 。 飞船总长.米,总重吨多, 飞船的设备达到余台,软件个,元器件万余件。,逃逸塔,飞船(整流罩),一级火箭,4个助推器,二级火箭,Back,中国航天飞行第一人 杨利伟,航天英雄杨利伟主动出舱,神州6号航天飞
17、行员 费俊龙 聂海胜,费俊龙 聂海胜,长征-2F火箭点火发射,抛弃逃逸塔,Go,飞行高度在0公里到110公里之间时, 万一火箭发生危及宇航员生命安全的故障, 它可以拖着轨道舱和返回舱与火箭分离, 并降落在安全地带,帮助飞船上的宇航员脱离险境。 可靠的飞船逃逸救生系统是 让宇航员放心巡天的“定心丸”, 被誉为宇航员“生命之塔”。,四个助推器分离,一级火箭,一级火箭分离,整流罩分离后视,二级火箭主发动机熄火,二级火箭和飞船分离,推进舱帆板展开,推进舱帆板对日定向,轨道舱帆板展开,轨道舱,返回舱,推进舱,Back,神舟七号载人航天, 2008年9月25日晚21时10分04秒 在酒泉卫星发射中心发射升
18、空, 9月27日下午16时30分 航天员翟志刚首次进行出舱活动, 28日17时13分安全着陆。,神州7号航天飞行员 翟志刚、刘伯明、景海鹏,神州6号飞船系统有70多万条软件语句, 北京航天指挥控制中心有140万条重要软件语句, 7000多个模块、关键软件模块1100余个。陈朝晖主要负责软件工作,他说,商用软件可以发测试版,即使出了问题大不了把电脑关机重启。可载人飞船上软件要求“零缺陷”,这在商用软件是难以想象的。为了保证制导、导航与控制分系统的可靠性,他说:“连1998年的休假条到今天我还没能用上。” 要保证火箭和飞船的正常工作达到“零缺陷”, 测试是最关键的因素之一!。,Go,测试的目标或定
19、义:(G.Myers,IBM软件测试专家) 1) 测试是为了发现程序中的错误而执行程序的过程; 2) 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案; 3) 成功的测试是发现了至今为止尚未发现的错误的测试。,7.2.1 软件测试的目标,三个发现,就是发现错误 测试的正确定义是:为了发现程序中的错误而执行程序的过程。 并不是;测试是为了表明程序是正确的;成功的测试是没有发现错误的测试 。 这与某些人通常想象的完全不同。, 由于测试的目标是暴露程序中的错误,从心理学角度看,由程序编写者自己进行测试是不恰当的,应有其他人测试; (肯定与否定) 应该认识到测试决不能证明程序是正确的。 因为我
20、们不能进行穷举测试(包含所有可能情况的测试) 结论:测试只能查找出程序中有错误,不能证明程序中没有错误。(可靠性增加),测试的目标或定义:(G.Myers,IBM软件测试专家) 1) 测试是为了发现程序中的错误而执行程序的过程; 2) 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案; 3) 成功的测试是发现了至今为止尚未发现的错误的测试。,7.2.1 软件测试的目标,722 软件测试的准则 1)所有的测试都应该能追溯到用户需求。测试结果最终要满足用户的需求。 (从用户角度看,最严重的错误是不能满足用户需求的那些错误) 2)尽早制定测试计划。在需求阶段制定测试计划,设计阶段制定测试方案
21、。 3)把Pareto原理应用到软件测试中。 80%的错误只与20%的模块有关,即错误集中在某些模块上。 IBM S/370操作系统中44%错误仅与4%的模块有关。 问题是怎样找出这些可疑的模块并彻底测试它们。,BACK,延边大学教务管理系统,学籍管理,成绩管理,选课管理,教学管理,绩点输入,成绩输入,成绩查询,成绩修改,统计,按学号查询,按课程查询,按班级查询,4) 从“小规模”测试开始,逐步进行“大规模”测试。单元-集成-整个系统。 5) 穷举测试是不可能的。 穷举(尽)测试:把程序中所有可能的执行路径都检查一遍的测试。由于受时间、人力和资源的限制,在测试中不可能执行每个可能的路径。因此,
22、测试只能证明程序中有错误,不能证明程序中没有错误。但是精心设计测试方案,有可能充分覆盖程序逻辑并使程序达到所要求的可靠性。 6) 为了最大可能发现错误,应该由独立的第三方从事测试。(否定的工作),穷举(尽)测试:只有将所有可能的情况都测试到,才有可能检查出所有的错误。但这是不可能的: 例:程序 P 有两个整型输入量 X、Y,输出量为Z,在32位机上运行。 所有的测试数据组(Xi,Yi)的数目为: 232232=264,1毫秒执行1次,共需5亿年。,7)软件测试难度大根据上述分析,既然不能进行 “穷举”测试, 又要查出尽可能多的错误,软件测试工作的难度大。 只有选择 “高效的测试用例”, 什么是
23、“高效的测试用例”? 如何选择“高效的测试用例”?这就是本章讨论的主要问题!,1. 测试用例应由输入数据和预期的输出数据 两部分组成,这样便于对照,有的放矢。,测试原则:(在测试中应遵循的原则),2. 测试用例,不仅选用合理的输入数据,还要选择不合理的输入数据,对不合理的输入数据,程序应拒绝接受,并输出相应的提示。 3. 除了应检查程序是否做了它应该做的事,还应该检查是否做了它不应该做的事。 例:打印信息时打出了用户并不需要的多余信息。,4. 应制定测试计划并严格执行,排除随意性。 5.长期保留测试用例,因为以后还要用。(修改后、维护) 6.对发现错误较多的程序段,应进行更深入的测试。 7.
24、程序员避免测试自己的程序。 心理障碍。肯定与否定 存在惯性思维方式,不能发现自己的错误,应由别人或另外机构来测试。,723 测试方法黑盒测试和白盒测试 黑盒测试:(功能测试) 如果已经知道产品应该具有的功能, 可以通过测试来检验是否每个功能都能正常使用。,买电视机时用户进行测试: 图像清晰、声音、色彩、灵敏度、选择频道、外观损坏。 不检查电路,白盒测试:(结构测试) 如果知道产品内部工作过程, 可以通过测试来检验产品内部动作是否 按照规格说明书的规定进行正常进行。在电路板上检查进出每个部件的电压是否正常。,一、黑盒测试(功能测试)把程序看成一个黑盒子,完全不考虑程序的内部结构和处理过程。 也就
25、是说, 1) 在程序的接口进行的测试; 2) 只检查程序功能是否能按规格说明书的规定正常使用; 3) 程序是否能适当地接收输入数据并产生正确地输出数据; 4)程序运行过程中能否保持外部信息(数据库或文件)的完整性。,Back,软件,输入:2,3,输出:5,SUM,Go,二白盒测试(结构测试):将程序看成,装在一个透明的盒子,完全知道程序的结构和算法。电路图和原理 也就是说, 按照程序内部的逻辑测试程序, 检测程序中的主要执行通路是否按要求正确工作。,不及格,及格,CJ=60,输入成绩:CJ,T,F,724 测试步骤 大型软件系统通常由若干个子系统组成, 每个子系统由许多模块组成。,BACK,延
26、边大学教务管理系统,学籍管理系统,成绩管理系统,选课管理系统,教学管理系统,绩点输入,成绩输入,成绩查询,成绩修改,统计,按学号查询,按课程查询,按班级查询,大型软件系统的测试基本上由5个步骤进行。 模块测试、子系统测试、系统测试、验收测试、 平行运行,需求分析,总体设计,详细设计,编程,模块测试,子系统测试,系统测试,验收测试,平行运行,BACK,1. 模块测试(单元测试)软件系统中每个模块完成一个相对独立的子功能。因此,可以把每个模块作为一个单独的实体来测试。 模块测试的目的:是保证每个模块作为一个单元能正常运行。 在模块测试过程中往往能发现编码和详细设计的错误。 模块测试是编码阶段的工作
27、,由程序设计者自己完成。,Go,2. 子系统测试 子系统测试是把经过单元测试的模块放在一起 形成一个子系统来测试。 “成绩管理”子系统 因为通过模块测试,一个模块作为一个单元能正常工作。 所以,模块之间协调和通信是主要问题,着重测试模块之间的接口。,Go1,Go2,3. 系统测试 :把经过测试的子系统装配成一个完整的系统来测试。教务管理系统 在系统测试中发现的往往是软件设计中的错误,也可能发现需求说明中的错误。 例如:选课管理系统中的某一个课程的学分与学籍管理系统中的相应课程的学分必须匹配。 如有错误应该是软件设计中的错误(子系统之间的连接)。 子系统和系统测试,通常称为集成测试;兼有检测和组
28、装含义。,Go1,Go2,4. 验收测试(确认测试) 把软件系统作为单一的实体进行测试,测试内容与系统测试基本类似。 但是在用户积极参与下,用实际数据(系统将来要处理的信息)进行测试。 目的是验证系统是否满足用户的需要。 发现的错误是需求规格说明书中的错误。,Go,5 . 平行运行(试运行) 关系重大的软件产品在验收测试后, 往往并不立即投入生产性运行, 而是要再经过一段平行运行时间的考验。 平行运行:用户在一段时期内同时运行新系统和旧系统, 以便比较新旧2个系统的处理结果。(一般是以旧系统正确为假设),具体目的是: 1) 可以在准生产环境下运行新系统而不冒风险。 (若新系统发生故障,可用旧系
29、统,再改新系统); 2)用户有一段熟悉新系统的时间; 3)检验用户文档(用户指南、用户手册、维护手册); 4)对新系统进行全负荷测试,验证性能指标。2008年10月24日(星期五)下午3点 ,学校召开“深入学习实践科学发展观”活动动员大会,要求全校教职工通过网络观看现场直播。结果网络拥挤登陆难,速度慢。,2007年10月30日, 北京奥运会门票面向境内公众第二阶段预售正式启动。 上午一开始,公众提交申请空前踊跃。 上午9时至10时, 官方票务网站的浏览量达到了800万次,系统瘫痪。 停止预售奥运会门票。 性能指标:800万次/时(没有达到),7.2.5 测试阶段的信息流,图7.1 测试阶段的信
30、息流,测试,评价,调试,可靠性 模型,软件配置,测试配置,测试结果,错误,错误率统计,预期结果,正确的程序,可靠性预测,2,3,SUM,5,?,源程序,哪个模块, 在哪些处理上,经常出现错误,BACK,输入信息: 1) 软件配置:需求说明书、设计说明书、源程序清单等 2) 测试配置:测试计划、测试方案测试方案包括: 测试时使用的输入数据, (2,3) 每组输入数据预定要检验的功能,(SUM) 预期结果。(每组输入数据预期应该得到的结果) ( 5 ) 3)评价:测试结果和预期的结果相比较,如果两者不同,则可能程序中有错误。如果两者相同,则程序可能没有错误,或有错误但没有发现(选择别的方案) 4)
31、调试:确定错误的准确位置,并改正它。编程人负责调式。 5) 可靠性模型:使用错误率数据,估计将来出现错误的情况,从而预测软件可靠性。,Go,73 单元测试(模块测试) 单元测试集中检验软件设计中的最小单元模块。在编写源程序代码后,用编译程序检查并且改正所有语法错误。(编译不能检查逻辑错误)以详细设计为指南,对重要的执行通路进行测试,以便发现模块内部的错误。 单元测试主要使用白盒测试技术, 而且对多个模块的测试可以并行地进行。,Go,731 测试重点 1. 模块接口 主要检查数据能否正确地通过模块。 如果数据不能正常的进出模块,其它的测试无法进行。 检查的主要内容是:模块调用时, 参数的数目、类
32、型、对应关系是否一致形参和实参 全局变量的定义在各个模块中是否一致。extern,2. 局部数据结构 对于模块来说,局部数据结构是常见的错误来源。 不正确的或不一致的数据说明; 错误的初始化或没有赋初值; 变量名未定义或拼写、缩写错误 数据类型不相容; 上溢、下溢和地址错误。 数组的上下标,dimension A(10), A(15)=5 8位字长,256=28:-128+127,3. 重要执行通路 由于不能进行穷举测试, 在单元测试时,选择最有代表性、最可能发现错误的执行通路进行测试是十分关键。 1) 计算中常见错误: 算术运算符优选次序不正确; 运算方式不正确; 初始化方式不正确; 精确度
33、不够; 表达式符号表示错误。,2) 比较中常见错误: 不同的数据类型比较; 逻辑运算符不正确或优选次序错误; 由于精确度误差造成的比较出错; 循环终止条件错误或死循环; 错误地修改循环变量等等。,4. 出错处理通路 要设置适当的处理错误的通路, 以便在真的出现错误时, 执行相应的出错处理通路或结束处理。 不仅应该在程序中包含出错处理通路, 而且应该认真测试这种通路。,5. 边界条件 程序最容易在边界上出错,如: 输入输出数据的等价类边界; 选择和循环条件的边界; 复杂数据结构(如,数组)的边界等等。,732 代码审查 人工测试源程序,可以由程序员自己非正式进行,也可由审查小组正式进行。 后者称
34、为代码审查,是一种非常有效的程序验证技术。 审查小组成员:组长、设计者、编写者、测试者。组长是很有能力的程序员,但未直接参与这项工程。,1)小组成员先研究设计说明书; 2)设计者简要介绍他的设计; 3)编写者详细介绍程序的逻辑。 4)小组其他成员力图发现其中的错误 5)当发现错误时由组长记录。 在大多数情况下, 通过向程序员提出关于他的程序的逻辑和他编写程序时所做的假设的疑问, 可以发现的错误比由计算机测试所发现的错误还多。,输入成绩,成绩应该大于等于0,小于等于100如果成绩=60,则显示及格,否则显示不及格,T,F,F,T,代码审查的优点(与计算机测试相比较): 1)一次审查会上发现许多问
35、题,减少测试总工作量。而用计算机测试的方法发现错误后,需要先改正错误才能继续测试,即,发现一个,改正一个,才能继续测试。 2)据统计代码审查可以发现30%70%的逻辑设计和编码错误。,733 计算机测试(单元测试用) 一个模块(B)虽然具有相对独立的子功能, 但不是一个完全独立的程序,其本身不能单独运行。 因此必须为需要测试的模块开发驱动模块和存根模块。 当测试B模块时,(其他模块还没有编程), 则应设计模拟M、D、E的模块才能进行测试。,Go,图7.2.1,测试数据,驱动 模块,测试结果,B,存根模块1,存根模块2,模拟 M,模拟 D,模拟 E,BACK,1)驱动模块(driver):用来模
36、拟被测试模块的上层调用模块。 它接收测试数据, 把这些数据传送给被测模块, 接收和输出测试结果。 2)存根模块(或桩,stub):用来模拟被测试模块所调用的模块。 接收数据, 它做少量的数据操作, 返回被测模块所需的信息。,Go,驱动、存根模块与实际模块的主要区别: 功能要比实际模块简单; 只实现被测模块正常运行所必须的基本功能,(通常是接收与发出参数)而不是全部功能。 驱动模块和存根模块在单元测试结束后就丢弃,增加了开销。,思考: 经过单元测试,解决了一个模块内的所有问题, 单个模块能正常工作, 那么, 能否保证模块组装后整个系统仍能正常工作? 为什么?,Go,74 集成测试 集成测试是测试
37、和组装软件的系统化技术。 集成测试:在单元测试的基础上, 将所有模块按照设计要求组装成一个完整的系统进行的测试。模块经过单元测试以后,发现并改正了每个模块中的错误, 表明各个模块能正常工作。但还需要把所有模块按照软件的结构图组装起来,构成一个系统。 (每个模块测试后,需要按延大教务管理结构图总体设计组装),Go,实践表明,单个模块能正常工作,不能保证组装后整个系统仍能正常工作!。 这是因为: 1) 单元测试使用的驱动模块和存根模块,与它们所代替的实际模块并不完全等效,因此单元测试有不彻底、不严格的情况; 2)各个模块组装起来,数据穿过接口时可能会丢失;(成绩修改结果立即反映到成绩统计上) 3)
38、 一个模块对另一个模块可能由于疏忽而造成有害影响; 4) 子模块(功能)组合起来可能不产生预期的主功能;(成绩查询,按学号查询正常,但按班级查询不正常),Go,5) 个别模块可以接受的误差,组装起来可能积累到不能接受的程度。6) 全程数据结构(外部变量)可能有问题。单元测试主要是检查局部数据结构。集成测试主要目标: 是发现与接口有关的问题(26与接口有关),Go,怎样合理的进行集成测试? 大致有以下集成测试方法:要掌握: 各种方法的原理和特点 比较不同方法的优缺点 根据需要选择使用,集 成 测 试,非渐增式测试,渐增式测试,自顶向下集成,自底向上集成,深度优先策略,宽度优先策略,1) 非渐增式
39、测试方法先分别测试每个模块,再把所有模块按设计要求组装在一起测试。 特点: 把单元测试和集成测试完全分离, 先进行单元测试,后进行集成测试,且一次性组装后进行测试。可以多人并行测试。 例如,有一个模块系统,图(I)。其单元测试和组装顺序如图(II),BACK,1,2,3,4,5,6,7,D:驱动程序 S:存根程序,A,C,B,D,E,M,Go,缺点?,BACK,d1,s1,d2,s2,d3,d4,d5,缺点: 为每个模块都设计一个D或S模块,工作量多;D= 5,S=5 一次性组装后测试,错误定位难。在哪个模块,哪个接口发生错误? 优点:可以多人并行测试。,Go,2)渐增式测试方法 :(逐渐增加
40、模块) 把下一个要测试的模块同已经测试好的模块 结合起来进行测试, 测试完以后再把下一个应该测试的模块结合 进来测试。 这种每次增加一个新模块都进行一次测试的方法。(结合一个,测试一个) 特点:单元测试和集成测试相结合进行测试。,BACK,M,1,:已经测试的模块:正在测试的模块,优点?,Go,M,A,s4,M,A,D,B,C,s5,E,BACK,优点: D或S模块数量少 D=0,S=5 发现错误定位容易,只能是新结合的模块及其接口部分发生错误。 有些模块(M)可进行多次回归测试。 缺点:只能一个人进行测试。,Go,因此,在进行集成测试时普遍使用渐增式测试方法。 但根据实际情况,尤其是大型系统
41、两种方法混合使用。渐增式方法又可分为, 自顶向下和自底向上2种集成方法。,741 自顶向下集成 自顶向下的集成是广泛使用的组装软件的方法。 因为总是有顶层模块, 它只需要存根程序,不需要驱动程序。 基本思路是: 从主控模块(主程序)开始,沿着软件的控制层次向下移动, 从而逐渐把各个模块结合起来。,s1,s2,s3,s4,s5,S1,S2,S3,S6,S5,S4,S7,但是按照软件结构层次向下移动方法也有2种方法: 深度优先策略、宽度优先策略。,Back,1)深度优先的策略: 先组装在软件结构的一条主控制通路上(纵向)的所有模块。 一般先选择关键通路。 左通路: M-A-D-G或M-AE) 中央
42、通路:M-B-F; 右通路: M-C,Go,2)宽度优先策略: 按照软件结构层次向下移动,把同一层次上的所有模块组装起来。 1) M 2) A-B-C; 3) D-E-F 4) G,Go,深度优先:早期发现和改正主要的关键路径的错误,并早期实现软件的一个关键的主要功能,增加开发人员和用户的信心。教务-成绩-成绩查询-学号。宽度优先:早期发现较高层次的错误有益处。教务-学籍、教学、成绩、选课(都是关键的抉择,通常位于上层),Go,自顶向下结合步骤如下: 第一步:对主控模块进行测试,测试时用存根程序代替所有直接下属的模块。如:用(S1、S2、S3)存根程序模拟A、B、C程序。 第二步:根据选定的结
43、合策略(深度或宽度), 每次用一个实际模块代替一个存根程序。(新结合进来的模块又需要新的存根程序)。 第三步:模块结合一个,测试一个。 第四步:为了保证加入模块没有引进新的错误,可能需要进行回归测试, (即,全部或部分地重复以前做过的测试) 从第二步开始不断地重复进行上述过程,直到构成完整的软件结构为止。,Go,742 自底向上集成 自底向上测试从“原子”模块(软件结构最低层模块) 开始进行组装和和测试。 因为是从底部向上结合模块,总是有低层模块。 只需要驱动程序,不需要存根程序。,自底向上结合的步骤如下: 第一步:分族:把低层模块组合成,实现某个特定的软件子功能的族,如;族1、2、3。查询、
44、统计、修改 第二步:为每一个族,写一个驱动程序,以协调测试数据的输入和输出。图中的虚线框D1、D2、D3分别是族1、2、3的驱动程序 第三步:对子功能族进行测试。 第四步:去掉驱动程序,用实际模块代替驱动模块;沿着软件结构自下向上移动,与上层模块结合测试。把子功能族组合起来形成更大的子功能族。,Mc,B,C,A,Ma,Mb,族1,族2,族3,第一步:分族,D2,D3,D1,第二步:为每一个族,写一个驱动程序,第三步:对子功能族进行测试。,族1,族2,族3,D1,D4,D2,D5,D3,D6,第四步:去掉驱动程序,用实际模块代替驱动程序,A,B,C,D7,A,Ma,B,D8,Mb,C,Mc,Ma
45、,Mb,优点: 1不需要驱动程序 2较早发现上层模块的接口错误; 3如果选择深度优先策略,可以早期实现软件的一个完整的子功能增强开发人员和用户双方的信心;缺点: 1需要存根程序; 2低层关键模块中的错误发现较晚; 3设计较多的存根模块,测试开销大; 4早期不能并行工作,不能充分利用人力,优点: 1不需要存根程序; 2低层模块的错误较早发现 3随着上移,驱动模块逐步减少,开销较少。 4早期可以并行工作 5比较容易设计测试用例缺点: 1需要驱动程序; 2上层模块错误发现的晚,而上层模块的问题是全局性问题,影响范围大。 3系统的整体功能最后才能看到。,7.4.3 两种方法比较自顶向下集成 自底向上集
46、成,一般说来,纯粹自顶向下或自底向上的策略可能都不实用, 实践中多使用混合策略: 1)改进的自顶向下测试方法基本上使用自顶向下方法, 但是在早期就使用自底向上的方法测试软件中 少数关键模块。 2)混合法 对软件结构中较上层,使用自顶向下方法; 对较下层使用自底向上的结合方法,两者结合。,744 回归测试 回归测试: 重新执行已经做过的测试的某一部分,防止出现由于结合新模块而引起的一些副作用。 回归测试,用于保证由于调试或其他原因(新结合模块)引起的变化,不会导致非预期的软件行为或额外的错误的测试活动。,75 确认测试 确认测试,也称为验收测试,它的目标是验证软件的有效性。 软件的有效性: 如果
47、软件的功能和性能符合需求规格说明书的规定,则软件是有效的。 需求规格说明书准确地描述了用户对软件的合理期望, 因此是软件有效的标准,也是验收测试的基础。,751 确认测试的范围 确认测试必须有用户积极参与,或者以用户为主进行。 确认测试属于黑盒测试。 确认测试的范围: 1) 对用户特别感兴趣的功能和性能需要增加测试; (经费的计算,响应时间,屏幕布局、颜色,输入/出格式) 2) 使用实际数据进行测试; 3) 按照用户的使用过程进行测试。,确认测试有两种可能的结果: (1) 功能和性能与用户要求一致,软件可以接受。 (2) 功能和性能与用户要求有差距,出现的问题与需求分析有关,解决比较困难。从头
48、开始,经费、时间?应分清责任, (以需求说明书为依据,是说明不清楚,还是理解错误)并与用户充分协商解决。,752 软件配置复查 软件配置复查目的是: 保证软件配置的所有成分都齐全, 质量都符合要求, 文档与程序完全一致。 软件配置包括: 1)用户所需文档(用户手册,操作手册); 2)设计文档; 3)源程序; 4)测试文档(测试说明书、测试报告等)。,753 Alpha测试和 Beta测试 如果软件是专为一个客户开发的,由最终用户进行验收测试。(教务管理系统) 如果一个软件是为许多客户开发的 (WINDOWS,OFFICE), 那么让每个客户都进行正式的验收是不现实的。 在这种情况下,大多数开发商都使用Alpha或Beta测试过程, 来发现那些看起来只有最终用户才能发现的错误。,