首页 软件测试概述

软件测试概述

举报
开通vip

软件测试概述软件测试概述 第七章 软件测试概述 信息技术的飞速发展,使软件产品应用到社会的各个领域,软件产品的质量自然成为人们共同关注的焦点。不论软件的生产者还是软件的使用者,均生存在竞争的环境中,软件开发商为了占有市场,必须把产品质量作为企业的重要目标之一,以免在激烈的竞争中被淘汰出局。用户为了保证自己业务的顺利完成,当然希望选用优质的软件。质量不佳的软件产品不仅会使开发商的维护费用和用户的使用成本大幅增加,还可能产生其他的责任风险,造成公司信誉下降,继而冲击股票市场。在一些关键应用 (如民航订票系统、银行结算系统、证券交易...

软件测试概述
软件测试概述 第七章 软件测试概述 信息技术的飞速发展,使软件产品应用到社会的各个领域,软件产品的质量自然成为人们共同关注的焦点。不论软件的生产者还是软件的使用者,均生存在竞争的环境中,软件开发商为了占有市场,必须把产品质量作为企业的重要目标之一,以免在激烈的竞争中被淘汰出局。用户为了保证自己业务的顺利完成,当然希望选用优质的软件。质量不佳的软件产品不仅会使开发商的维护费用和用户的使用成本大幅增加,还可能产生其他的责任风险,造成公司信誉下降,继而冲击股票市场。在一些关键应用 (如民航订票系统、银行结算系统、证券交易系统、自动飞行控制软件、军事防御和核电站安全控制系统等) 中使用质量有问题的软件,还可能造成灾难性的后果。 软件危机曾经是软件界甚至整个计算机界最热门的话题。为了解决这场危机,软件从业人员、专家和学者做出了大量的努力。现在人们已经逐步认识到所谓的软件危机实际上仅是一种状况,那就是软件中有错误,正是这些错误导致了软件开发在成本、进度和质量上的失控。有错是软件的属性,而且是无法改变的,因为软件是由人来完成的,所有由人做的工作都不会是完美无缺的。问题在于我们如何去避免错误的产生和消除已经产生的错误,使程序中的错误密度达到尽可能低的程度。   给软件带来错误的原因很多,具体地说,主要有如下几点: ①、交流不够、交流上有误解或者根本不进行交流   在应用应该做什么或不应该做什么的细节(应用的需求)不清晰的情况下进行开发。 ②、软件复杂性   图形用户界面(GUI),客户/服务器结构,分布式应用,数据通信,超大型关系型数据库以及庞大的系统规模,使得软件及系统的复杂性呈指数增长,没有现代软件开发经验的人很难理解它。 ③、程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 错误   象所有的人一样,程序员也会出错。 ④、需求变化   需求变化的影响是多方面的,客户可能不了解需求变化带来的影响,也可能知道但又不得不那么做。需求变化的后果可能是造成系统的重新设计,设计人员的日程的重新安排,已经完成的工作可能要重做或者完全抛弃,对其他项目产生影响,硬件需求可能要因此改变,等等。如果有许多小的改变或者一次大的变化,项目各部分之间已知或未知的依赖性可能会相互影响而导致更多问题的出现,需求改变带来的复杂性可能导致错误,还可能影响工程参与者的积极性。 ⑤、时间压力   软件项目的日程表很难做到准确,很多时候需要预计和猜测。当最终期限迫近和关键时刻到来之际,错误也就跟着来了。 ⑥、自负人更喜欢说:   '没问题'   '这事情很容易'   '几个小时我就能拿出来'   太多不切实际的‘没问题’,结果只能是引入错误。 ⑦、代码文档贫乏   贫乏或者差劲的文档使得代码维护和修改变的异常艰辛,其结果是带来许多错误。事实上,在许多机构并不鼓励其程序员为代码编写文档,也不鼓励程序员将代码写得清晰和容易理解,相反他们认为少写文档可以更快的进行编码,无法理解的代码更易于工作的保密(“写得艰难必定读的痛苦”)。 ⑧、软件开发工具   可视化工具,类库,编译器,脚本工具,等等,它们常常会将自身的错误带到应用软件中。就象我们所知道的,没有良好的工程化作为基础,使用面向对象的技术只会使项目变得更复杂。 为了更好地解决这些问题,软件界做出了各种各样的努力。   人们曾经认为更好的程序语言可以使我们摆脱这些困扰,这推动了程序设计语言的发展,更多的语言开始流行,为了使程序更易于理解开发了结构化程序设计语言,如PL/1,PASCAL等;为了解决实时多任务需求开发了结构化多任务程序设计语言,如Modula,Ada等;为了提高重用性开发了面向对象的程序设计语言,如Simlasa等;为了避免产生不正确的需求理解,开发形式化描述语言,如HAL/S等,这使得建立基于自然语言的描述成为可能,人们以形式化语言来描述需求;为了支持大型数据库应用,开发了可视化工具,如Visual Studio、Power Builder等。程序语言对提高软件生产效率起到了一定的积极作用,但它对整个软件质量尤其是可靠性的影响,与其他因素相比作用较小。   可能是因为程序语言基于严格的语法和语义规则,人们企图用形式化证明方法来证明程序的正确性。将程序当作数学对象来看待,从数学意义上证明程序是正确的是可能的。数学家对形式化证明方法最有兴趣,在论文上谈起来非常吸引人,但实际价值却非常有限,因为形式化证明方法只有在代码写出来之后才能使用,这显然太迟了,而且对于大的程序证明起来非常困难。 受到其他行业项目工程化的启发,软件工程学出现了,软件开发被视为一项工程,以工程化的方法来进行规划和管理软件的开发。   在可以借助许多新的技术和工具进行软件开发的今天,软件开发过程的成熟性问题开始引起人们的重视。这种产品一致性问题的主要症结在于管理,因此人们将目标转向了管理的改善,一些以改进软件开发过程为目标的活动已经展示出积极的结果。 不论采用什么技术和什么方法,软件中仍然会有错。采用新的语言、先进的开发方式、完善的开发过程,可以减少错误的引入,但是不可能完全杜绝软件中的错误,这些引入的错误需要测试来找出,软件中的错误密度也需要测试来进行估计。 测试是所有工程学科的基本组成单元,是软件开发的重要部分。自有程序设计的那天起测试就一直伴随着。统计表明,在典型的软件开发项目中,软件测试工作量往往占软件开发总工作量的40%以上。而在软件开发的总成本中,用在测试上的开销要占30%到50%。如果把维护阶段也考虑在内,讨论整个软件生存期时,测试的成本比例也许会有所降低,但实际上维护工作相当于二次开发,乃至多次开发,其中必定还包含有许多测试工作。因此,测试对于软件生产来说是必需的,问题是我们应该思考“采用什么方法、如何安排测试?” 第一节 测试的基本概念 一、目的与任务 G.J.Myers在他的名著《软件测试技巧》一书中,给出了测试的定义:“程序测试是为了发现错误而执行程序的过程”。根据这一定义,测试(Testing)的目的与任务可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个与测试有关的术语叫纠错(Debugging)。它的目的与任务可以 规定 关于下班后关闭电源的规定党章中关于入党时间的规定公务员考核规定下载规定办法文件下载宁波关于闷顶的规定 为: 目的:定位和纠正错误; 任务:消除软件故障,保证程序的可靠运行。 测试与纠错的关系,可以用图7.1的数据流图来说明。图中表明,每一次测试都要准备好若干必要的测试数据,与被测试程序一道送入计算机执行。通常把程序执行需要的测试数据,称为一个“测试用例(Testing Case)”。每一个测试用例产生一个相应的“测试结果”。如果它与“期望结果”不相符合,便说明程序中存在错误,需要用纠错来改正。 测试数据 期望结果 程序 测试结果 错误信息 改正信息 图 7.1 对于长度仅有数百行的小程序,测试与纠错一般由编码者一人完成;但对于大型的程序,测试与纠错必须分开进行。为了保证大程序的测试不受干扰,通常都把它交给独立的小组进行,等发现了程序有错误,再退回编码者进行纠错。 有人把小程序得测试和纠错合称为“调试”。一旦编好了一个小程序,先拿到机器上测试,发现错误便进行纠错,修改后再重复测试。这一交替进行的“测试-纠错-再测试-再纠错”的过程,常被通俗的称为“调试程序”。其实“调试”在英语中并无相当的词,但纠错时有一种常用的工具叫“Debugger”,通常被称为调试程序,而不译为纠错程序。 二、测试的特性 与 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 、设计、编码等工作相比,程序测试具有若干特殊的性质。了解这些性质,将有助于我们正确处理和做好测试工作。 1、​ 挑剔性 测试时对质量的监督与保证,所以“挑剔”和“揭短”很自然的成为测试人 员奉行的信条。测试是为了证明程序有错,而不是证明程序无错。因此,对于被测程序就是要“吹毛求疵”,就是要在“鸡蛋里面挑骨头”。只有抱着为证明程序有错的目的去测试,才能把程序中潜在的大部分错误找出来。 2、​ 复杂性 人们常常以为开发一个程序是困难的,测试一个程序则是比较容易的,这其 实是误解。设计测试用例是一项需要细致和高度技巧的工作,稍有不慎就会顾此失彼,发生不应有的疏漏。 举一个极简单的例子。假如一个程序的功能是输入3个数作为三角形的3条边,然后鉴别这一三角形的类别。输入3个”5”时程序回答“等边三角形”,但若输入3个“0”程序也回答“等边三角形”,就真假不分了。又如,三条便分别为2、3、4时应判断是“不等边三角形”,但如果对2、3、5或2、3、6也判断为“不等边三角形”,也会闹笑话。可见在设计测试用例时,需要考虑到各种可能出现的情况,对被测程序进行多方面的考核。切忌挂一漏万,把原本复杂的问题想的过于简单。小程序尚且如此,大型程序就可想而知了。所以有人认为,搞好一个大型程序的测试,其复杂性不亚于对这个程序的开发,主张挑选最有才华的程序员来参加测试工作。 3、​ 不彻底性 “程序测试只能证明错误的存在,但不能证明错误不存在”。这句话揭示了 测试所固有的一个重要性质――不彻底性。 可能有人认为,测一遍不彻底可以测十遍,十遍不彻底可以测百遍。需要 多少测试用例就用多少测试用例,难道还怕达不到彻底吗? 为了回答这个问题,举一个例子。假如有人开发了一个C语言的编译程序,要对它进行彻底的测试,需要设计多少个测试用例呢?从正面说,该编译程序应能把一切符合语法的C程序正确的翻译为目标程序;从反面说,它应能对一切有语法错误的C程序指出程序的语法。显然,这两个“一切都是无穷量”,十无法实现的。所谓彻底测试就是让被测程序在一切可能的输入情况下全部执行一遍。通常称这种测试为“穷举测试(Exhaustive Testing)”。实际测试中,穷举测试要不是像上例那样根本无法实现,就是工作量太大(例如一个小程序要连续测试许多年),在实践上行不通。这就注定了一切实际测试都是不彻底的,当然也就不能保证测试后的程序不存在遗留的错误。 4、​ 经济性 既然穷举测试行不通,所以在程序测试中,总是选择一些典型的、有代表性 的测试用例,进行有限的测试。通常把这种测试称为“选择测试(Selective Testing)”,为了降低测试成本(一般占整个开发成本的1/3左右),选择测试用例时应注意遵守“经济性”的原则。所以,第一,要根据程序的重要性和一旦发生故障将造成的损失开确定它的可靠性等级,不要随意提高等级,从而增加测试的成本;第二,要认真研究测试策略,以便能使用尽可能少的测试用例,发现尽可能多的程序错误。 三、测试的种类 静态分析器分析 (自动方式) 代码会审 静态分析 代码评审 走查 (程序不执行) 办公桌检查 程序 (人工方式) 测试 黑盒测试(测试程序功能) 动态测试 (程序执行) 白盒测试(测试程序结构) 图7.2 测试是一个执行程序的过程,即要求被测程序在机器上运行。其实,不执行程序也可以发现程序的错误。为便于区分,一般把前者称为“动态测试”,后者称为“静态分析(Static Analysis)”。广义的说,它们都属于程序测试,详见图7.2 顾名思义,静态分析就是通过对被测程序的静态审查,发现代码中潜在的错误。它一般用人工方式脱机完成,故亦称为人工测试或代码评审(Code Review);也可借助于静态分析器在机器上以自动方式进行检查,但不要求程序本身在机器上运行。按照评审的不同组织形式,代码评审又可区分为代码会审、走查盒办公桌检查3种。对某个具体的程序,通常只使用一种评审方式。代码会审是由一组人通过阅读、讨论和争议对程序进行静态分析的过程。会审小组由组长,2~3名程序设计和测试人员及程序员组成。会审小组在充分阅读待审程序文本、控制流程图及有关要求、规范等文件基础上,召开代码会审会,程序员逐句讲解程序的逻辑,并展开热烈的讨论甚至争议,以揭示错误的关键所在。实践表明,程序员在讲解过程中能发现许多自己原来没有发现的错误,而讨论和争议则进一步促使了问题的暴露。例如,对某个局部性小问题修改方法的讨论,可能发现与之有牵连的甚至能涉及到模块的功说明、模块间接口和系统总结构的大问题,导致对需求定义的重定义、重设计验证,大大改善了软件的质量。 动态测试也可区分为两种。一类把被测程序看成一个黑盒,根据程序的功能来设计测试用例,称为黑盒测试(Black Box Testing);另一类则根据被测程序的内部结构设计测试用例,测试者需事先了解被测程序的结构,故称为白盒测试(White Box Testing)。 四、测试的文档 为了保证测试质量,软件测试必须完成规定的文档。按照软件工程的要求,测试文档主要应包括测试 计划 项目进度计划表范例计划下载计划下载计划下载课程教学计划下载 和测试 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 两个方面的内容。 测试计划的主体是“测试内容说明”。它包括测试项目名称,实测结果与期望结果的比较,发现的问题,以及测试达到的效果等。 测试报告的主体是“测试结果”,它包括测试项目名称,实测结果与期望结果的比较,发现的问题,以及测试达到的效果等。 一个程序所需的测试用例可以定义为: 测试用例={测试数据+期望结果} 式中的{}表示重复。它表明,测试一个程序要使用多个测试用例,而每一个测试用例都应包括一组测试数据和一个相应的期望结果。如果在测试用例后面再加“实际结果”,就成为“测试结果”,即 测试结果={测试数据+期望结果+实际结果} 由此可见,测试用例不仅是连接测试计划与执行的桥梁,也是软件测试的中心内容。有效的设计测试用例,是搞好软件测试的关键。 第二节 黑盒测试 黑盒测试就是根据被测程序功能来进行测试,所以也称为功能测试。用黑盒法设计测试用例,有4种常用技术,本节将逐一进行介绍。 一、等价分类法 所谓等价分类(Equivalence Partitioning),就是把输入数据的可能值划分为若干等价类,使每类种的任何一个测试用例,都能代表同一等价类种的其它测试用例。换句话说,如果从某一等价类种任意选出一个测试用例未能发现程序的错误,就可以合理的认为在该类中的其它测试用例也不会发现程序的错误。这样,就把漫无边际的随机测试变成有针对性的等价类测试,有可能用少量有代表性的例子来代替大量内容相似的测试,借以实现测试的经济性。 采用这一技术要注意一下两点:一是划分等价类不仅要考虑代表“有效”输入值的有效等价类,还须考虑代表“无效”输入值的无效等价类;二是每一无效等价类至少要用一个测试用例,不然就可能漏掉某一类错误,但允许若干有效等价类合用同一个测试用例,以便进一步减少测试的次数。下面请看一个例子。 例7.1 某工厂招工,规定报名者年龄应在16周岁到35周岁之间(到2002年3月30日止)。即出生年月不在上述范围内,将拒绝接受,并显示“年龄不合格”等出错信息。试用等价类法设计对这一程序功能的测试用例。 解 第一步:划分等价类。假定已知出生年月由6位数字字符表示,前4位代表年,后2位代表月,则可以划分为3个有效等价类,7个无效等价类,如表7.2所示。 输入数据 有效等价类 无效等价类 出生年月 (1)6位数字字符 (2)有非数字字符 (3)少于6个数字符 (4)多于6个数字符 对于数值 (5)在196702~198603之间 (6)<196702 (7)>198603 月份对应数值 (8)在1~12之间 (9)等于“0” (10)>12 第二步:设计有效等价类需要的测试用例。如表7.2中的(1)(5)(8)等3个有效等价类,可以公用一个测试用例,例如: 测试数据 期望结果 测试范围 197011 输入有效 (1)(5)(8) 第三步:为每一个无效等价类至少设计一个测试用例。本例具有7个无效等价类,需要不少于7个测试用例。例如: 测试数据 期望结果 测试范围 MAY,70 输入无效 (2) 19705 输入无效 (3) 1968011 输入无效 (4) 195512 年龄不合格 (6) 196006 年龄不合格 (7) 196200 输入无效 (9) 197222 输入无效 (10) 让几个有效等价类公用一个测试用例,可以减少测试次数,有利而无弊;但若几个无效等价类合用一个测试用例,就可能使错误漏检。就上例而言,假定把“195512”(对应无效等价类(6))和“196200”(对应无效等价类(9))合并为一个测试用例,例如“195500”及使在测试过程中程序显示出“年龄不合格”的信息,仍不能证明程序对月份为“00”的输入数据也具有识别和拒绝接受的功能。再进一步讲,其实在第一步“划分等价类”时,就应防止有意或无意的将几个独立的无效等价类写成一个无效等价类。例如,若在上例中把(9)(10)两个无效等价类合并写成“末两位的对应值为0或>12”则与之相应的测试用例也将从原来的2个减为1个,对程序的测试就不够完全了。 二、边界值分析法 实践表明,程序员在处理边界情况时,很容易因疏忽或考虑不周发生编码错误。例如,在数组容量、循环次数以及输入数据与输出数据的边界值附件程序出错的概率往往较大。采用边界值分析法(Boundary Value Analysis),就是要这样来选择测试用例,使得被测试程序能在边界值及其附件运行,从而更有效的暴露程序中潜藏的错误。我们仍以例7.1为例说明。 例7.2 程序同例7.1。试用边界值分析法设计其测试用例。 解 用等价类法设计测试用例时,测试数据可以在等价类值域内任意选取。就拿例7.1来说,为了只接受年龄合格的报名者,程序中可能设有语句: if (196702<=value(birthdate)<=198603) then read(birthdate) else write “invalid age” 但如果编码时把以上语句中的“<=”无写为“<”用例7.1中的所有测试用例都不能发现这种错误。所谓边界值分析,就是要把测试的重点放在各个等价类的边界上,选取刚好等于、大于和小于边界值的数据为测试数据,并据此设计出相应的测试用例。 从例7.1可知,本例有3个输入等价类,即(1)出生年月;(2)对于数值;(3)月份对应数值。采用边界值分析法,可为这3个输入等价类选取14个边界值测试用例,(其中有两个相重,实有13个),其内容如下: 输入等价类 测试用例说明 测试数据 期望结果 选取理由 出生年月 1个数字字符 5个数字字符 7个数字字符 有1个非数字字符 全是非数字字符 6个数字字符 5 19705 1968011 19705A AUGUST 输入无效 输入有效 仅有一个合法字符 比有效长度恰少一个字符 比有效长度恰多一个字符 非法字符最少 非法字符最多 类型与长度均有效的输入 196702 对应数值 35周岁 16周岁 >35周岁 <16周岁 合格年龄 不合格年龄 最大合格年龄 最小合格年龄 恰大于合格年龄 恰小于合格年龄 198603 196701 198604 月份对应数值 月份为1月 月份为12月 月份<1 月份>12 196702 198603 196700 197413 输入有效 输入无效 最小月份 最大月份 恰小于最小月份 恰大于最大月份 表7.3 说明:表中第6、第七两个测试用例数据相同,可合用一个测试用例。 将例7.1和例7.2进行比较,可见: (1)​ 等价类分类法的测试数据是在各个等价类允许的值域内任意选取的,而边界值分析的数据必须在边界值附件选取; (2)​ 例7.1用了8个测试用例,而例7.2用了13个。一般的说,用边界值分析法设计的测试用例比等价分类法代表性更广,发现错误的能力也更强。但是对于边界的分析与确定比较复杂,要求测试人员具有更多的经验和创造性。 还需要指出,例7.2包含的边界值情况比较简单,只需要分析输入等价类。在有些情况下,除了考察输入值边界外,还需要考虑输出值和其它可能存在的边界。例如,假定被测程序是一个计算X的函数Sin(X),其输出具有3个边界值-1,0和1。则在选择测试用例时,应使X的值分别产生上述的3种输出边界值,即选取-∏/2、0、∏/2作为X的测试数据。 三、错误猜测法 所谓猜错(Error Guessing),就是猜测被测程序在哪些地方容易出错,然后针对可能的薄弱环节来设计测试用例。显然,它比前两种方法更多的依靠测试人员的直觉与经验。所以,一般都先用前两种方法设计测试用例,然后用猜错法补充一些例子作为辅助的手段。 仍以上述的报名程序为例,在已经用等价类法和边界值法设计过测试用例的基础上,还可以用猜错法补充一些测试用例,例如: (1)​ 出生年月为“0” (2)​ 漏送“出生年月”; (3)​ 年月次序颠倒,例如将“197012”误输为“121970”等。 四、因果图法 1)因果图的适用范围 前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系。如果在测试时考虑输入条件的各种组合,可能又会产生一些新情况。 所有输入条件之间的组合情况往往相当多。必须考虑使用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例,这就需要利用因果图。因果图方法最终生成的是判定表。它适合于检查程序输入条件的各种组合情况。 2)用因果图生成测试用例的基本步骤 (1)分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识。 (2)分析软件规格说明描述中的语义,找出原因与结果之间、原因与原因之间对应的是什么关系?根据这些关系,画出因果图。 (3)由于语法或环境限制,有些原因与原因之间、原因与结果之间的组合情况不可能出现。为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。 (4)把因果图转换为判定表 (5)把判定表的每一列拿出来作为依据,设计测试用例。 3)在因果图中出现的基本符号 (a)​ 恒等C1 ○ ○ E1 (b)​ 非 C1○ ~ ○ E1 (c)​ 或 C1○ ∨ ○E1 C2○ (d)​ 与 C1○ ∧ ○E1 C2○ 通常在因果图中用Ci表示原因,用Ei表示结果,其基本符号如图7所示。主要的原因和结果之间的关系有: (a)​ 恒等:表示原因与结果之间一对一的对应关系。若原因出现,则结果也出现。若原因不出现,则结果也不出现。 (b)​ 非:表示原因与结果之间的一种否定关系。若原因出现,则结果不出现。若原因不出现,反而结果出现。 (c)​ 或:表示若几个原因中有一个出现,则结果出现,只有当这几个原因都不出现时,结果才不出现。 (d)​ 与:表示若几个原因都出现,结果才出现。若几个原因中有一个不出现,结果就不出现。 4)表示约束条件的符号 为了表示原因与原因之间、结果与结果之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。若从输入(原因)考虑,有以下四种约束: 输入 (1)E(互斥):表示a,b两个原因不会同时成立,两个中最多有一个可能成立。 (2)I(包含):表示a,b,c三个原因中至少有一个必须成立。 (3)O(唯一):表示a和b当中必须有一个,且仅有一个成立。 (4)R(要求):表示当a出现时,b必须也出现。不可能a出现,b不出现。 输出(5)M(屏蔽):表示当a是1时,b必须是0。而当a为0时,b的值不定。 5)利用因果图设计测试用例的实例 【例】有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。规格说明为:“若投入5角钱或1元钱的硬币,押下【橙汁】或【啤酒】的按钮,则相应的饮料就送出来。若售货机没有零钱找,则一个显示【零钱找完】的红灯亮,这时在投入1元钱硬币并押下按钮后,饮料不送出来而且1元硬币也退出来;若有零钱找,则显示【零钱找完】的红灯灭,在送出饮料的同时退还5角硬币。” (1)分析这一段说明,列出原因和结果 原 因 1、售货机有零钱找 2、投入1元钱 3、投入5角钱 4、押下橙汁按钮 5、押下啤酒按钮 结 果 21、售货机【零钱找完】灯亮 22、退还1元硬币 23、退还5硬币 24、送出橙汁饮料 25、送出啤酒饮料 (2)画出因果图,如下7.3所示。所有原因结点列在左边,所有结果结点列在右边。建立两个中间结点,表示处理的中间状态。 (3)由于2与3,4与5不能同时发生,分别加上约束条件E (4)把因果图转换成判定表 在因果图中,阴影部分表示因违反约束条件的不可能出现的情况,删去。第16列与第32列因什么动作也没做,也删去。最后可根据剩下的16列作为确定测试用例的依据。 序号 条 件 ① ②③ ④⑤ 中间结果 (11) (12) (13) (14) 结 果 (21) (22) (23) (24) (25) 测试用例 第三节 白盒测试 白盒测试以程序的结构为依据,所有又称为结构测试。早期的白盒测试把注意力放在流程图的各个判定框,使用不同的逻辑覆盖标准来表达对程序进行测试的详尽程度。随着测试技术的发展,人们越来越重视对程序执行路径的考察,并且用程序图代替流程图来设计测试用例。为了区分这两种白盒测试技术,以下把前者称为逻辑覆盖测试,后者称为路径测试。 一、逻辑覆盖测试 逻辑覆盖测试法(Logic Coverage Testing)考察的重点是图中的判定框(菱形框)。因为这些判定若不是与选择结构有关,就是与循环结构有关,是决定程序结构的关键成分。 按照对被测程序所作测试的有效程度,逻辑覆盖测试可由弱到强区分为5种覆盖标准: 发现错误的能力 弱 强 语句覆盖 每条语句至少执行一次 判定覆盖 每一判定的每个分支至少执行一次 条件覆盖 每一判定中的每个条件,分别按“真”、“假”至少各执行一次 判定/条件覆盖 同时满足判定覆盖和条件覆盖的要求 条件组合覆盖 求出判定中所有条件的各种可能组合值,每一可能的条件组合至少执行一次 举例说明: 有一个程序段如下: a b F T c d F T e (a)​ 语句覆盖:设计若干个测试用例,运行被测程序,使得每一个可执行语句至少执行一次。例如在上图所给出的例子中,正好所有的可执行语句都在路径L1(a->c->e)上,所以选择路径L1设计测试用例,就可以覆盖所有的可执行语句。 L1(a->c->e) ={(A>1) and (B=0) } and {(A=2) or (x/A>1)} =(A=2) and (B=0) or {(A>1) and (B=0) and (x/A>1)} 测试用例可以设计为:【(2,0,4),(2,0,3)】覆盖ace【L1】 从程序中每个可执行语句都得到执行这一点来看,语句覆盖的方法似乎能够比较全面的检验每一个可执行语句。但与后面介绍的其它覆盖相比,语句覆盖是最弱的逻辑覆盖准则。 (b)​ 判定覆盖 所谓判定覆盖就是设计若干个测试用例,运行被测试程序,使得程序中每个判断的取真分支和取假分支至少经历一次。判定覆盖又称为分支覆盖。如上例如果选择路径L1(a->c->e)和L2(a->b->d),可得满足要求得测试用例: L2(a->b->d) ={(A<=1) or (B≠0) } and {(A≠2) and (x<=1)} =( A<=1) and (x<=1) or {( B≠0) and (A≠2) and (x<=1)} 测试用例可以设计为: 【(2,0,4),(2,0,3)】覆盖ace【L1】 【(1,1,1),(1,1,1)】覆盖abd【L2】 如果选取路径L3(a->b->e)和L4(a->c->d) L3(a->b->e) ={(A<=1) or (B≠0) } and {(A=2) or (x>1)} ={( A<=1) and (x>1)} or {( B≠0) and (A=2) } or {( B≠0) and (x>1)} L4(a->c->d) ={(A>1) and (B=0) } and {(A≠2) and (x/A<=1)} 还可以得到另一组可用得测试用例: 【(2,1,1),(2,1,2)】覆盖abe【L3】 【(3,0,3),(3,1,1)】覆盖acd【L4】 所有测试用例得取法不唯一。注意有例外情况,例如,如果把上例中第二个判定中的条件x>1错写成x<1,那么利用上面两组测试用例,仍能得到同样的结果。这表明,只是判定覆盖,还不能保证一定能查出在判断得条件中存在得错误。因此还需要更强的逻辑覆盖准则检验判断内部条件。 (c)​ 条件覆盖 所谓条件覆盖就是设计若干个测试用例,运行被测程序,使得程序中每个判断的每个条件的可能取值至少执行一次。上例中,我们事先可对所有条件得取值加以标记。例如: 对于第一个判断:条件A>1取真值为T1,取假值为T1 条件B=1取真值为T2,取假值为T2 对于第二个判断:条件A=2取真值为T3,取假值为T3 条件x>1取真值为T4,取假值为T4 则可选取测试用例如下: 测试用例 通过路径 条件取值 覆盖分支 【(2,0,4),(2,0,3)】 ace(L1) T1 T2 T3 T4 c,e 【(1,0,1),(1,0,1)】 abd(L2) T1 T2 T3 T4 b,d 【(2,1,1),(2,1,2)】 abe(L3) T1 T2 T3 T4 b,e 或 测试用例 通过路径 条件取值 覆盖分支 【(1,0,3),(1,0,4)】 abe(L3) T1 T2 T3 T4 c,e 【(2,1,1),(2,1,2)】 abe(L3) T1 T2 T3 T4 b,d 注意,前一组测试用例不但覆盖了所有判断得取真分支和取假分支,而且覆盖了判断中所有条件得可能取值。但是后一组测试用例虽满足了条件覆盖,但只覆盖了第一个判断得取假分支和第二个判断得取真分支,不满足判定覆盖得要求。为了解决这一矛盾,需要对条件和分支兼顾,有必要考虑以下得判定-条件覆盖。 (d)​ 判定-条件覆盖 所谓判定-条件覆盖就是设计足够的测试用例,使得判断中每个条件得所有可能取值至少执行一次,同时每个判断本身的所有可能判断结果至少执行一次。上例中可以设计如下测试用例: 测试用例 通过路径 条件取值 覆盖分支 【(2,0,4),(2,0,3)】 ace(L1) T1 T2 T3 T4 c,e 【(1,1,1),(1,1,1)】 abd(L2) T1 T2 T3 T4 b,d 判定-条件覆盖也有缺陷。从表面上来看,它测试了所有条件得取值,但是事实并非如此。因为往往某些条件掩盖了另一些条件。对于条件表达式 (A>1)and (B=0)来说,若(A>1)的测试结果为真,则还有测试(B=0),才能决定表达式得值;而若(A>1)的测试结果为假,可以立刻确定表达式得结果为假。这时往往就不再测试(B=0)的取值了。因此,条件(B=0)就没有检查。 同样,对于条件表达式(A=2)or (X>1)来说,若(A=2)得测试结果为真,就可以立即确定表达式的结果为真。这时,条件(X>1)就没有检查。因此,采用判定-条件覆盖,逻辑表达式中的错误不一定能够查得出来。 (e)​ 条件组合覆盖 所谓条件组合覆盖就是设计足够得测试用例,运行被测程序,使得每个判断得所有可能得条件取值组合至少执行一次。上例中,先对各个判断得条件取值组合加以标记。如下: 记 1​ A>1,B=0 作T1 T2,属第一个判断得取真分支; 2​ A>1,B≠0 作T1 T2,属第一个判断得取假分支; 3​ A≯1,B=0 作T1 T2,属第一个判断得取假分支; 4​ A≯1,B≠0 作T1 T2,属第一个判断得取假分支; 5​ A=2,x>1 作T3 T4,属第二个判断得取真分支; 6​ A=2,x≯1 作T3 T4,属第二个判断得取真分支; 7​ A≠2,x>1 作T3 T4,属第二个判断得取真分支; 8​ A≠2,x≯1 作T3 T4,属第二个判断得取假分支; 对于每个判断,要求所有可能得条件取值得组合都必须取到。测试用例如下: 测试用例 通过路径 条件取值 覆盖分支 【(2,0,4),(2,0,3)】 ace(L1) T1 T2 T3 T4 ①,⑤ 【(2,1,1),(2,1,2)】 abe(L3) T1 T2 T3 T4 ②,⑥ 【(1,0,3),(1,0,4)】 abe(L3) T1 T2 T3 T4 ③,⑦ 【(1,1,1),(1,1,1)】 abd(L2) T1 T2 T3 T4 ④,⑧ 这组测试用例覆盖了所有条件得可能取值的组合,覆盖了所有判断得可取分支,但路径漏掉了L4。测试还不完全。 【练习】 写出“直接插入排序”的算法,画出流程图,并用逻辑覆盖法,写出测试用例。 【解】已知直接插入排序算法得基本步骤如下: (1)​ 从一组数中取出第一个数 (2)​ 取下一个数,如数已取完,则排序结束; (3)​ 如果所取数大于等于其前邻数,则重复(2)步 (4)​ 如果所取数小于其前邻数,则与其前邻数交换位置 (5)​ 重复第(4)步,直到所取已无前邻数(即已交换到当前数列得第一位置),或大于等于其前邻数为止 (6)​ 返回第(2)步。 流程图如下: 图7.5 排序部分的流程图 程序代码如下(PASCAL) PROGRAM bubblesort(input,output) LABEL 99; CONST n=100 VAR A:ARRAY[1..n] of integer; I,j,k,temp:INTEGER; BEGIN READLN(k); FOR I:=1 to k DO read(a[i]); FOR I:=2 to k DO BEGIN IF a[i]>=a[i-1] then goto 99; For j:=I downto 2 do Begin Temp:=a[j]; A[j]:=a[j-1]; A[j-1]:=temp; End 99: END For I:=1 to k do write(a[i]) End. 【设计测试用例】 由以上分析可知,排序程序具有双重嵌套循环结构。其内外循环体各包含一条选择语句,用于在条件满足时提前推出循环。程序中得4个判断是测试时考察得重点。以下分别列出按不同覆盖标准设计得测试用例: (1)​ 语句覆盖。稍作分析便不难看出,只要送入先大后小得两个数,程序执行时就可以遍历流程图中的所有框。因此,仅需选用一组测试数据如 {A={8,4},K=2},就能实现语句覆盖。这类覆盖发现错误得能力不强,例如若将程序中得两个“>=”均误写为“=”,用上述得测试数据就不能发现。 (2)​ 判定覆盖。选用上述得测试数据,内、外层循环都是从正常得循环出口退出得。要实现判定覆盖,还需在语句覆盖得基础上,增加两个能使程序从非正常出口退出的测试数据。例如,用以下两组数据: {A={8,4,8},K=3}和{A={8,4,4},K=3} 或 {A={8,4,8,4},K=4} 则程序将在满足A[I]=A[I-1]或A[J]=A[J-1]的条件下通过非正常出口,也能实现判定覆盖。但又可能出现另一种偏向,掩盖把“>=”误写为“=”的错误,造成更加严重得测试漏洞。 (3)​ 条件覆盖。从以上分析很容易想到,必须选取足够得测试,使复合条件占的每个条件分别按“真”、“假”出现一次,才能克服前述的缺点,进一步提高发现错误的能力。测试用例: {A={8,4,9,6},K=4} {A={8,4,8,4},K=4} 就能对程序实现条件覆盖。此时A[I](或A[J])大于、等于或小于A[I-1](或A[J-1])的3中情况将分别至少出现一次,无论把“>=”误写为“>”或“=”,都可用这两组数据检查出来。 (4)​ 其它覆盖。本例中得两个复合条件,其组成条件都不是互相独立的。如果其中有一个条件(例如A[I]=A[I-1] )为真,则另一个条件(例如 A[J]=A[J-1])必然为假。所有就本例来说,判定条件覆盖及条件组合覆盖都没有实际意义,可以不必讨论。 由此可见,本例宜选择条件覆盖,以便得到较强得查错能力。测试数据可选择 {A={8,4,9,6},K=4} {A={8,4,8,4},K=4} 或合成一组: {A={8,4,8,4,9,6},K=6} 二、路径测试 逻辑覆盖测试引导人们把注意力集中在程序得各个判定部分,抓住了结构测试的重点。但是另一方面,它却忽略了另一个对测试也有重要影响的方面-程序的执行路径。随着程序结构复杂性的增长和测试技术的发展,人们逐渐认识到这种忽略所带来的缺陷。于是,着眼于程序执行路径得测试方法便应运而生。这就是路径测试(Path Testing)。 路径测试离不开程序图。下面先对程序图作一简单介绍。 1、​ 程序图(Program Graph) 程序图实际上是一种简化了的流程图。在路径测试中,它是用来考察测试路径得有用工具。图7.6显示了分别用流程图和程序图来表示的基本控制结构,流程图中各种不同形状的框,在程序图中都被简化为用圆圈表示得一个个结点。由于程序图保留了控制流得全部轨迹,舍弃了各框得细节,因而画面简洁,路径清楚,用它来验证各种测试数据对程序执行路径的覆盖情况,比流程图更加方便。还有两点需要说明: (1)​ 顺序执行的多个结点,在程序图中可以合并画成一个结点,如图7.7所示。 (2)​ 含有复合条件的判定框,在程序图中常常先分解成几个简单条件判定框,然后再画,如图7.8所显示。 (a)流程图 (b)程序图 图7.6 程序图与流程图得对照图形 图7.7合并结点得程序图 图7.8分解为简单条件结点后得程序图 2、路径测试的特征 所谓路径测试,就是对程序图中每一条可能的程序执行路径至少测试一次。如果程序中含有循环(在程序图中表现为环),则每个循环至少执行一次。 路径测试具有以下特征: (1)​ 满足结构测试的最低要求。有些作者主张,语句覆盖加判定覆盖应是对白盒测试的最低要求。他们把同时满足这两种标准的覆盖取名为“完全覆盖(Complete Coverage)”从上述对路径测试的要求可见,它本身就包含了语句覆盖和判定覆盖(在程序图中分别称为点覆盖和边覆盖)。换句话说,只要满足了路径覆盖,就必然满足完全覆盖,也即满足了白盒测试的最低要求。 (2)​ 有利于安排循环测试。循环测试是路径测试的一个重要部分。从程序的执行路径而不是单纯从判定的角度来测试程序,有利于对程序中包含的循环结构进行更有效的测试。一般的说,对单循环结构的路径测试可包括: 1.​ 零次循环,即不执行循环体,直接从循环入口跳到出口 2.​ 一次循环,循环体仅执行一次,注意检查在循环初始化中肯存在的错误 3.​ 典型次数的循环 4.​ 最大值次循环,如果循环次数存在最大值,应按次最大值进行循环,需要时还可增加比最大值次数少一次或多一次的循环测试。 3、选择测试路径的原则 (1)​ 选择具有功能含义的路径 (2)​ 尽量用短路经代替长路径 (3)​ 从上一条测试路径到下一条测试路径,应尽量减少变动的部分(包括变动的边和结点) (4)​ 由简入繁,如果可能,应先考虑不含循环的测试路径,然后补充对循环的测试 (5)​ 除非不得已(如为了覆盖某条边),不要选取没有明显功能含义的复杂路径。 4、路径测试举例 【举例】仍以“直接插入排序”的算法为例,设计测试用例 【解】(1)将图7.5的流程图转换成程序图,如图7.9所示,在将其逆时针旋转90度,在把所有结点和边记上标号,如图7.10所示 h g a b c d e f m l n AE I k j 图7.10 图7.9 根据流程图导出的程序图 (2)按照上述选择路径的原则选择足够多的路径,使之覆盖所有的结点和边,如下表所示。 测试数据 覆盖的结点 ① ②③④⑤⑥⑦⑧ ⑨ 覆盖的边 a b c d e f g h I j k l m n q A={4,8},k=2 A={4,4},k=2 A={4,8,8},k=3 A={8,4},k=2 A={8,4,4},k=3 A={8,4,6},k=3 √√ √√ √√√ √√ √√√ √√ √√√√√√√√√ √√√√√√√√√ √√√√√√√√√ √√ √ √√ √√√ √ √√ √√√ √√ √√ √√√ √√√ √√ √ √√ √√√ √√√ √√ √√ √√ √√√ √√√ √√ √ √ √√ 以上6次测试已达到最低覆盖要求——完全覆盖。 (3)补充几项测试,见下表 循环测试内容 测试数据 外循环零次 外循环最大次,内循环零次 外循环最大次,那循环最大次 A={4},K=1 A={1,2…,99,100},K=100 A={100,99,…2,1},K=100 第四节 测试用例设计 以上讨论了软件测试的黑盒与白盒技术。本小节以两个简单程序为例,说明怎样从被测程序的实际出发,来确定测试策略和选择测试用例。需要指出的是,黑盒法与白盒法均包括多种技术,各有所长。但若单独采用其中的一种技术,都不能产生被测程序所需要的全部测试用例。因此在实际的程序测试中,总是将各种技术结合起来,取长补短,形成综合的测试策略。 一、黑盒测试用例设计 【例1】假设现有以下的三角形分类程序。该程序的功能是,读入代表三角形边长的3个整数,判定它们能否组成三角形。如果能够,则输出三角形是等边、等腰或任意三角形的分类信息。图9.11显示了该程序的流程图和程序图。为以上的三角形分类程序设计一组测试用例。 F T F F T F F F T T F 图9.11三角形程序的流程图和程序图 【解】第一步:确定测试策略。在本例中,对被测程序的功能有明确的要求,即:(1)判断能否组成三角形;(2)识别等边三角形;(3)识别等腰三角形;(4)识别任意三角形。因此可首先用黑盒法设计测试用例,然后用白盒法验证其完整性,必要时再进行补充。 第二步:根据本例的实际情况,在黑盒法中首先可用等价分类法划分输入的等价类,然后用边界值分析法和猜错法作补充。 等价分类法: 有效等价类 输入3个正整数: (1)3数相等 (2)3数中有2个数相等,比如AB相等 (3)3数中有2个数相等,比如BC相等 (4)3数中有2个数相等,比如AC相等 (5)3数均不相等 (6)2数之和不大于第3数,比如最大数是A (7)2数之和不大于第3数,比如最大数是B (8)2数之和不大于第3数,比如最大数是C 无效等价类: (9)含有零数据 (10)含有负整数 (11)少于3个整数 (12)含有非整数 (13)含有非数字符 边界值法: (14)2数之和等于第3数 猜错法: (15)输入3个零 (16)输入3个负数 第三步:提出一组初步的测试用例,如下表所示: 序号 测试内容 测试数据 期望结果 A B C 1 2 3 4 5 6 7 8 9 10 11 12 等边 等腰 任意 非三角形 退化三角形 零数据 负数据 遗漏数据 非整数 非数字符 5,5,5 4,4,5 3,4,5 9,4,4 8,4,4 0,4,5 0,0,0 -3,4,5 -3,-4,-5 3,4 3.3,4,5 A,4,5 5,5,4 4,9,4 4,8,4 4,0,5 3,-4,5 4,5,4 4,4,9 4,4,8 4,5,0 3,4,-5 等边三角形 等腰三角形 任意三角形 不是三角形 运行出错 (类型不符) 第四步:用白盒法验证第三步产生的测试用例的充分性。结果表明,上表中的前8个测试用例,已能满足对被测程序图的完全覆盖,不需要再补充其他的测试用例。 二、白盒测试用例设计 【例2】学生成绩查询程序,最多可以存放100个学生的成绩,按学号排序。如果输入的学号在这批学生内,就输出该学生的成绩,否则便回答“学号??没有找到”。程序采用折半查找,另外,当输入学号为“0”时,即结束查找。为该程序设计测试用例。 【解】 第一步:确定测试策略。折半查找时实现查找的一种算法。就本例而言,主要应测试程序在各种典型情况下能否有效的实现查找,并选择正确的执行路径。因此,路径覆盖法显然是比较合理的测试策略。 第二步:令成绩表的长度为1项或小于100项的任意项(例如5项)。在成绩表的不同位置上每次查+/-1个学生,考察其执行情况: 1​ 成绩表只有1项,查0个学生 2​ 成绩表只有1项,查1学生(是成绩表中的学生) 3​ 成绩表只有1项,查2学生(都不是成绩表中的学生) 4​ 成绩表只有5项,查1学生(正好是表的中间项) 5​ 成绩表只有5项,查1学生(正好是表的上半部分) 6​ 成绩表只有5项,查1学生(正好是表的下半部分) 7​ 成绩表只有5项,查1学生(不是表中的学生) 测试数据下表所示,由表可知,以上测试数据已达到对程序图的“完全覆盖”。 说明:测试数据中略去score数组的数据。本例中它们可以取任意值,不会影响测试结果。 第三步:成绩表长度为最大值(100项)。连续查找学号为最小值、比最小值小1、最大值、比最大值大1、中间值以及上半、下半表中典型值的7个学生。具体测试数据可以是: K=100,studentno={101,102,…,199,200} Num={100,101,200,201,150,130,170,0} 从以上3步可见: 1​ 虽然是路径测试,同时也测试了程序的功能,例如: ​ 只查一个学生,连续查多个学生,或一个学生不查; ​ 成绩表长度为1项,为100项,或为任意项(例如5项) 2​ 虽然是按白盒法设计的测试用例,也运用了黑盒法中的等价类分类与取边缘值等思想。 从前面的两个例子可知,设计测试用例的过程,实际上也是对黑盒测试技术与白盒测试技术综合运用的过程。我们不可能期望只靠几条简单的规则就能解决各种实际问题,恰恰相反,有些做法“可以意会,不能言传”,真正需要的倒是举一反三,灵活的运用在黑盒和白盒测试中所蕴涵的原则和思想。 a b q A c d BB B e C J k F i D E G h F n L m 测试数据 覆盖结点 覆盖的边 ①②③④⑤⑥⑦⑧⑨⑩ a b c d e f g h I j k l m n q K=1 studentno={100} num={0} ={100,0} ={90,110,0} k=5 studentno ={2,4,6,8,10} num={6,0} ={2,0} ={8,0} ={9,0} √√ √ √√√√ √√√ √√√√√ √√√ √√√√ √√√ √√√√ √√√ √√√ √√√√ √√√ √√√ √√√√ √√√ √√√ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ A:first=1,last=k,middle=int((first+last)/2) B:num=studentno[middle] or last=first C:num
本文档为【软件测试概述】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_371440
暂无简介~
格式:doc
大小:275KB
软件:Word
页数:32
分类:互联网
上传时间:2011-07-23
浏览量:49