1、第7章 实现,1 编码 2 软件测试基础 3 单元测试 4 集成测试 5 确认测试 6 白盒测试技术 7 黑盒测试技术 8 调试 9 软件可靠性,1. 实现:包括编码和测试。 2. 编码:就是把软件设计结果翻译成用某种程序设计语言书写的程序。 3. 测试: 1)无论怎样强调软件测试的重要性和它对软件可靠性的影响都不过分; 2)测试的目的就是在软件投入生产性运行之前,尽可能多地发现软件中的错误; 3)软件测试在软件生命周期中横跨两个阶段; 4)调试:是测试阶段最困难的工作。,1. 程序设计语言是人和计算机通信的最基本的工具,它的特点必然会影响人的思维和解题方式,因此,编码之前的一项重要工作就是选
2、择一种适当的程序设计语言。2. 汇编语言和高级语言,7.1 编码 7.1.1 选择程序设计语言,1)汇编语言:使用汇编语言编码需要把软件设计翻译成机器操作的序列,由于这两种表示方法很不相同,因此汇编程序设计既困难又容易出差错。 2)高级语言一般都容许用户给程序变量和子程序赋予含义鲜明的名字,通过名字很容易把程序对象和它们所代表的实体联系起来;此外,高级语言使用的符号和概念更符合人的习惯。因此,用高级语言写的程序容易阅读,容易测试,容易调试,容易维护。,3. 选择程序设计语言的理想标准:. 理想的模块化机制;. 可读性好的控制结构和数据结构;. 良好的独立编译机制。 4. 实用标准:. 系统用户
3、的要求;. 可以使用的编译程序;. 可以得到的软件工具;. 工程规模;. 程序员的知识;. 软件可移植性要求. 软件的应用领域,7.1.2 编码风格, 表面看来,软件测试的目的与软件工程所有其他阶段的目的都相反; 测试阶段的根本目标:是尽可能多地发现并排除软件中潜藏的错误,最终把一个高质量的软件系统交给用户使用; 但是,仅就测试本身而言,它的目标可能和许多人原来设想的很不相同。,7.2 软件测试基础,G.Myers给出了关于测试的一些规则,这些规则 也可以看作是测试的目标或定义: 1) 测试是为了发现程序中的错误而执行程序的过程; 2) 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案
4、; 3) 成功的测试是发现了至今为止尚未发现的错误的测试。,7.2.1 软件测试的目标,为了能设计出有效的测试方案,软件工程师必须深入理解 并正确运用指导软件测试的基本准则。 所有测试都应该能追溯到用户需求; 应该远在测试开始之前就制定出测试计划; 把Pareto原理应用到软件测试中;Pareto原理:测试发现的错误中的80%很可能是由程序中20%的模块造成的; 应该从“小规模”测试开始,并逐步进行“大规模”测试; 5. 穷举测试是不可能的; 6. 为了达到最佳的测试效果,应该由独立的第三方从事测试工作。,7.2.2 软件测试准则,1. 白盒测试法 是可以把程序看成装在一个透明的白盒子里,测试
5、者完全知道程序的结构和处理算法。这种方法按照程序内部的逻辑测试程序,检测程序中的主要执行通路是否都能按预定要求正确工作。 是知道产品的内部工作过程,可以通过测试来检验产品内部动作是否按照规格说明书的规定正常进行。 因此,白盒测试又称为结构测试。,7.2.3 测试方法,2. 黑盒测试法 是把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程。也就是说,黑盒测试是在程序接口进行的测试,它只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当地接收输入数据并产生正确的输出信息,程序运行过程中能否保持外部信息的完整性。 是已经知道了产品应该具有的功能,可以通过测试来检验是否每个功能都能正
6、常使用。 因此,黑盒测试又称为功能测试。,大型软件系统的测试过程基本上由下述几个步骤组成: 1. 模块测试模块测试的目的是保证每个模块作为一个单元能正确运行,所以模块测试通常又称为单元测试。在这个测试步骤中所发现的往往是编码和详细设计的错误。,7.2.4 测试步骤,2. 子系统测试子系统测试是把经过单元测试的模块放在一起形成一个子系统来测试。 3. 系统测试系统测试是把经过测试的子系统装配成一个完整的系统来测试。 4. 验收测试 验收测试把软件系统作为单一的实体进行测试; 验收测试的目的是验证系统确实能够满足用户的需要,在这个测试步骤中发现的往往是系统需求说明书中的错误。验收测试也称为确认测试
7、。,5. 平行运行 平行运行:就是同时运行新开发出来的系统和将被它取代的旧系统,以便比较新旧两个系统的处理结果。这样做的具体目的有如下几点: (1) 可以在准生产环境中运行新系统而又不冒风险; (2) 用户能有一段熟悉新系统的时间; (3) 可以验证用户指南和使用手册之类的文档; (4) 能够以准生产模式对新系统进行全负荷测试,可以用测试结果验证性能指标。,测试阶段的输入信息有两类: (1) 软件配置:包括需求说明书、设计说明书和源程序清单等;(2) 测试配置:包括测试计划和测试方案。所谓测试方案不仅仅是测试时使用的输入数据,还应该包括每组输入数据预定要检验的功能,以及每组输入数据预期应该得到
8、的正确输出。,7.2.5 测试阶段的信息流,图1 测试阶段的信息流, 单元测试又称为模块测试,集中检测软件设计的最小单元模块;通常,单元测试和编码软件属于过程的同一个阶段。 在编写出源程序代码并通过了编译程序的语法检查之后,就可以对重要的执行通路进行测试,以便发现模块内部的错误。 单元测试主要使用白盒测试技术,而且对多个模块的测试可以并行地进行。 可以应用人工测试和计算机测试这样两种不同类型的测试方法,完成单元测试工作。,7.3 单元测试,1. 模块接口 首先应该对通过模块接口的数据流进行测试,如果数据不能正确地进出,所有其他测试都是不切实际的。 2. 局部数据结构 对于模块来说,局部数据结构
9、是常见的错误来源。 应该仔细设计测试方案,以便发现局部数据说明、初始化、默认值等方面的错误。,7.3.1 测试重点,3. 重要的执行通路 由于通常不可能进行穷尽测试,因此,在单元测试期间选择最有代表性、最可能发现错误的执行通路进行测试十分关键; 应该设计测试方案用来发现由于错误的计算、不正确的比较或不适当的控制流而造成的错误。 4. 出错处理通路 好的设计应该能预见出现错误的条件,并且设置适当的处理错误的通路,以便在真的出现错误时执行相应的出错处理通路或干净地结束处理。 不仅应该在程序中包含出错处理通路,而且应该认真测试这种通路。,5. 边界条件 边界测试是单元测试中最后的也可能是最重要的任务
10、。 软件常常在它的边界上失效,故使用刚好小于、刚好等于和刚好大于最大值或最小值的数据结构、控制量和数据值的测试方案,非常可能发现软件中的错误。, 人工测试源程序可以由编写者本人非正式地进行,也可以由审查小组正式进行。后者称为代码审查。 审查小组最好由下述 4 人组成: 组长; (2) 程序的设计者; (3) 程序的编写者; (4) 程序的测试者。,7.3.2 代码审查, 审查方法:方法1: 小组成员应该先研究设计说明书,力求理解这个设计。 为了帮助理解,可以先由设计者扼要地介绍他的设计。 再由程序的编写者解释他是怎样用程序代码实现这个设计的,通常是逐个语句地讲述程序的逻辑。 对照程序设计常见错
11、误清单,分析审查这个程序。当发现错误时由组长记录下来,审查会继续进行。,方法2: 称为预排: 由一个人扮演“测试者”,其他人扮演“计算机”。 会前测试者准备好测试方案,会上由扮演计算机的成员模拟计算机执行被测试的程序。 在大多数情况下,通过向程序员提出关于他的程序的逻辑和他编写程序时所做的假设的疑问,可以发现的错误比由测试方案直接发现的错误多。, 模块不是一个独立的程序,因此必须为每个单元测试开发驱动软件和(或)存根软件。 驱动程序:就是一个“主程序”,它接收测试数据,把这些数据传送给被测试的模块,并且印出有关的结果。 存根程序代替被测试的模块所调用的模块。因此存根程序也可以称为“虚拟子程序”
12、。,7.3.3 计算机测试,图7.2 正文加工系统的层次图,. TEST STUB(*测试正文编辑模块用的存根程序*)初始化;输出信息“进入了正文编辑程序”;输出“输入的控制信息是”CFUNCT;输出缓冲区中的字符串;IF CFUNCT=CHANGETHEN把缓冲区中第二个字改为*ELSE在缓冲区的尾部加?END IF;输出缓冲区中的新字符串; END TEST STUB,. TEST DRIVER(*测试正文编辑模块用的驱动程序*)说明长度为2500个字符的一个缓冲区;把CFUNCT置为希望测试的状态;输入字符串;调用正文编辑模块;停止或再次初启; END TEST DRIVER, 集成测试
13、包括子系统测试和系统测试; 集成测试是测试和组装软件的系统化技术,主要目标是发现与接口有关的问题。 由模块组装成程序时有两种方法:1.非渐增式测试方法2.渐增式测试方法3.比较,7.4 集成测试, 当使用渐增方式把模块结合到程序中去时,有自顶向下和自底向上两种集成策略。7.4.1 自顶向下集成 思想:从主控制模块开始,沿着程序的控制层次向下移动,逐渐把各个模块结合起来。在把附属于(及最终附属于)主控制模块的那些模块组装到程序结构中去时,或者使用深度优先的策略,或者使用宽度优先的策略。 深度优先的结合方法:先组装在软件结构的一条主控制通路上的所有模块。 而宽度优先的结合方法:是沿软件结构水平地移
14、动,把处于同一个控制层次上的所有模块组装起来。,图7.3 自顶向下结合, 把模块结合进软件结构的具体过程由下述4个步骤完成:1. 对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块;2. 根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序;3. 在结合进一个模块的同时进行测试;4. 为了保证加入模块没有引进新的错误,可能需要进行回归测试(即,全部或部分地重复以前做过的测试)。 从第二步开始不断地重复进行上述过程,直到构造起完整的软件结构为止。, 自顶向下集成的优点:自顶向下的结合策略能够在测试的早期对主要的控制或关键的抉择进行检验。如果主要控制确
15、实有问题,早期认识到这类问题是很有好处的,可以及早想办法解决。 自顶向下集成方法的问题:最常见的是:为了充分地测试软件系统的较高层次,需要 在较低层次上的处理。 解决方法:1. 把许多测试推迟到用真实模块代替了存根程序以后再进行;这种方法失去了在特定的测试和组装特定的模块之间的精确对应关系,这可能导致在确定错误的位置和原因时发生困难。2. 从层次系统的底部向上组装软件。,自底向上测试从软件结构最低层的模块开始组装和测试。 自底向上测试不需要存根程序。 自底向上的结合策略:1. 把低层模块组合成实现某个特定的软件子功能的族;2. 写一个驱动程序(是用于测试的控制程序),协调测试数据的输入和输出;
16、3. 对由模块组成的子功能族进行测试;4. 去掉驱动程序,沿软件结构自下向上移动,把子功能族组合起来形成更大的子功能族。 上述第二步到第四步实质上构成了一个循环。,7.4.2 自底向上集成,图7.4 自底向上结合, 自顶向下测试方法的主要优点是:1. 不需要测试驱动程序;2. 能够在测试阶段的早期实现并验证系统的主要功能,而且能在早期发现上层模块的接口错误。 自顶向下测试方法的主要缺点是:1. 需要存根程序,可能遇到与此相联系的测试困难;2. 低层关键模块中的错误发现较晚,3. 而且用这种方法在早期不能充分展开人力。 可以看出,自底向上测试方法的优缺点与自顶向下测 试方法的优缺点刚好相反。,7
17、.4.3 不同集成测试策略的比较, 混合策略:1. 改进的自顶向下测试方法基本上使用自顶向下的测试方法,但是在早期使用自底向上的方法测试软件中的少数关键模块。它的缺点也比自顶向下方法多一条,即测试关键模块时需要驱动程序。2. 混合法对软件结构中较上层使用的自顶向下方法与对软件结构中较下层使用的自底向上方法相结合。当被测试的软件中关键模块比较多时,这种混合法可能是最好的折衷方法。, 回归测试:是指重新执行已经做过的测试的某个子集,以保证上述这些变化没有带来非预期的副作用。 更广义地说,回归测试就是用于保证由于调试或其他原因引起的变化,不会导致非预期的软件行为或额外错误的测试活动。,7.4.4 回
18、归测试, 确认测试:也称为验收测试,它的目标是验证软件的有效性。 验证:指的是保证软件正确地实现了某个特定要求的一系列活动, 确认:指的是为了保证软件确实满足了用户需求而进行的一系列活动。 软件有效性的一个简单定义是: 如果软件的功能和性能如同用户所合理期待的那样,软件就是有效的。,7.5 确认测试, 确认测试必须有用户积极参与,或者以用户为主进行; 确认测试通常使用黑盒测试法; 应该仔细设计测试计划和测试过程,测试计划包括要进行的测试的种类及进度安排,测试过程规定了用来检测软件是否与需求一致的测试方案。通过测试和调试要保证软件能满足所有功能要求;能达到每个性能要求,文档资料是准确而完整的,此
19、外,还应该保证软件能满足其他预定的要求。 确认测试有下述两种可能的结果: 1. 功能和性能与用户要求一致,软件是可以接受的;2. 功能和性能与用户要求有差距。,7.5.1 确认测试的范围, 确认测试的一个重要内容是复查软件配置。 复查的目的是保证软件配置的所有成分都齐全,质量符合要求,文档与程序完全一致,具有完成软件维护所必须的细节,而且已经编好目录。 7.5.3 Alpha和Beta测试 如果软件是专为某个客户开发的,可以进行一系列验收测试,以便用户确认所有需求都得到满足。 如果一个软件是为许多客户开发的,在这种情况下,绝大多数软件开发商都使用被称为Alpha测试和Beta测试的过程,来发现
20、那些看起来只有最终用户才能发现的错误。,7.5.2 软件配置复查, Alpha测试由用户在开发者的场所进行,并且在开发者对用户的“指导”下进行测试。开发者负责记录发现的错误和使用中遇到的问题。总之,Alpha测试是在受控的环境中进行的。 Beta测试由软件的最终用户们在一个或多个客户场所进行,Beta测试是软件在开发者不能控制的环境中的“真实”应用。用户记录在Beta测试过程中遇到的一切问题,并且定期把这些问题报告给开发者。接收到在Beta测试期间报告的问题之后,开发者对软件产品进行必要的修改,并准备向全体客户发布最终的软件产品。, 设计测试方案:1)是测试阶段的关键技术问题;2)所谓测试方案
21、:包括具体的测试目的,应该输入的测试数据和预期的结果。3)设计测试方案的基本目标是:确定一组最可能发现某个错误或某类错误的测试数据。,7.6 白盒测试技术,所谓逻辑覆盖:是对一系列测试过程的总称,这组测试过程逐渐进行越来越完整的通路测试。1. 语句覆盖1)含义是:选择足够多的测试数据,使被测程序中每个语句至少执行一次。2)为了使每个语句都执行一次,程序的执行路径应该是sacbed,为此只需要输入下面的测试数据(实际上X可以是任意实数):A=2,B=0,X=4 3)语句覆盖是很弱的逻辑覆盖标准。,7.6.1 逻辑覆盖,图7.5 被测试模块的流程图,例1. 设计下列伪码程序的语句覆盖和路径覆盖测试
22、用例: START INPUT(A, B, C) IF A5THEN X=5ELSE X=1 END IF IF B10THEN Y=20ELSE Y=2 END IF IF C15THEN Z=30ELSE Z=3 END IF PRINT(X, Y, Z) STOP,语句覆盖的典型测试用例: 1) 3个判定表达式的值全为假输入:A=1, B=1, C=1预期的输出:X=1, Y=2, Z=3 2) 3个判定表达式的值全为真输入:A=10, B=20, C=30预期的输出:X=10, Y=20, Z=30,路径覆盖的测试用例: 1) (T, T ,T) 5) (F, F, F) 2) (T,
23、 T, F) 6) (F, F, T) 3) (T, F, F) 7) (F, T, F) 4) (T, F, T) 8) (F, T, T),2. 判定覆盖 1)判定覆盖又叫分支覆盖; 2)含义是:不仅每个语句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次,也就是每个判定的每个分支都至少执行一次。 3)能够覆盖路径sacbed和sabd或者sacbd和sabed的测试数据,都满足判定覆盖标准。. A=3,B=0,X=3; TF. A=2,B=1,X=1; FT 4)判定覆盖比语句覆盖强,但是对程序逻辑的覆盖程度仍然不高.,3. 条件覆盖 1)含义是:不仅每个语句至少执行一次
24、,而且使判定表达式中的每个条件都取到各种可能的结果。,. A=2,B=0,X=4; sacbed . A=1,B=1,X=1; sabd,2) 条件覆盖通常比判定覆盖强,因为它使判定表达式中每个条件都取到了两个不同的结果,判定覆盖却只关心整个判定表达式的值。,a: A1, A1, B=0, B0; b: A=2, A2, X1, X1;,4. 判定/条件覆盖 1) 含义是: 选取足够多的测试数据,使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可能的结果。 2) . A=2,B=0,X=4; sacbed, TT. A=1,B=1,X=1; sabd, FF 3)
25、有时判定/条件覆盖也并不比条件覆盖更强。,5. 条件组合覆盖 1) 它要求选取足够多的测试数据,使得每个判定表达式中条件的各种可能组合都至少出现一次。 2) 显然,满足条件组合覆盖标准的测试数据,也一定满足判定覆盖、条件覆盖和判定/条件覆盖标准。因此,条件组合覆盖是前述几种覆盖标准中最强的。 3) 但是,满足条件组合覆盖标准的测试数据并不一定能使程序中的每条路径都执行到,如sacbd。,。,对于左图,共有8种可能的条件组合: 1. A1, B=0 2. A1, B0 3. A1, B=0 4. A1, B0 5. A=2, X1 6. A=2, X1 7. A2, X1 8. A2, X1,.
26、 A=2,B=0,X=4; sacbed, 1和5, TT . A=2,B=1,X=1; sabed, 2和6, FT. A=1,B=0,X=2; sabed, 3和7, FT. A=1,B=1,X=1; sabd, 4和8, FF,例2. 设计下列伪码程序的分支覆盖和条件组合覆盖测试用例:STARTINPUT(A, B, C, D)IF (A0) AND (BO)THEN X=A+BELSE X=A-BEND IFIF (CA) OR (DB)THEN Y=C-DELSE Y=C+DEND IFPRINT(X, Y)STOP,6. 点覆盖 1) 图论中点覆盖的概念定义如下:如果连通图G的子图
27、G是连通的,而且包含G的所有结点,则称 G是G的点覆盖。 2) 在正常情况下流图是连通的有向图,满足点覆盖标准要求。 3) 可以选取足够多的测试数据,使得程序执行路径至少经过流图的每个结点一次,由于流图的每个结点与一条或多条语句相对应,显然,点覆盖标准和语句覆盖标准是相同的。,7. 边覆盖 1) 图论中边覆盖的定义是:如果连通图G的子图G是连通的,而且包含G的所有边,则称G是G的边覆盖。 2) 为了满足边覆盖的测试标准,要求选取足够多测试数据,使得程序执行路径至少经过流图中每条边一次。通常边覆盖和判定覆盖是一致的。 8. 路径覆盖含义是,选取足够多测试数据,使程序的每条可能路径都至少执行一次(
28、如果程序图中有环,则要求每个环至少经过一次)。,1. 基本路径测试 1) 基本路径测试是Tom McCabe提出的一种白盒测试技术。 2) 使用这种技术设计测试用例时,首先计算程序的环形复杂度,并用V(G)为指南定义执行路径的基本集合,从该基本集合导出的测试用例可以保证程序中的每条语句至少执行一次,而且每个条件 在执行时都将分别取真、假两种值。,7.6.2 控制结构测试, 使用基本路径测试技术设计测试用例的步骤如下:第一步, 根据过程设计结果画出相应的流图。例: 用基本路径测试技术测试下面的用PDL描述的求平均值过程。1. 画出流图PROCEDURE average; /* 这个过程计算不超过
29、100个在规定值域内的有效数字的平均 值;同时计算有效数字的总和及个数。*/INTERFACE RETURNS average, total.input, total.valid;INTERFACE ACCEPTS value, minimum, maximum;TYPE value1100 IS SCALAR ARRAY;TYPE average, total.input, total.valid;minimum,maximum, sum IS SCALAR;TYPE i IS INTEGER;,1: i=1; total.input=total.valid=0;sum=0; 2: DO W
30、HILE valuei -999 3: AND total.input=minimum 6: AND valuei0 END average,10: IF total.valid0 11: THEN average=sum/total.valid; 12: ELSE average=-999; 13: ENDIFEND average,图7.6 求平均值过程的流图,第二步,计算流图的环形复杂度。 第三步,确定线性独立路径的基本集合。 1) 所谓独立路径:是指至少引入程序的一个新处理语句集合或一个新条件的路径,用流图术语描述,独立路径至少包含一条在定义该路径之前不曾用过的边。 2) 使用基本路径
31、测试法设计测试用例时,程序的环形复杂度决定了程序中独立路径的数量,而且这个数是确保程序中所有语句至少被执行一次所需的测试数量的上界。,下面列出了 6 条独立路径: 路径1:12101113 路径2:12101213 路径3:123101113 路径4:12345892. 路径5:123456892. 路径6:1234567892. 路径4,5,6后面的省略号表示,可以后接通过控制结构其余部分的任意路径。,第四步,设计可强制执行基本集合中每条路径的测试用例。 可以测试上一步得出的基本集合的测试用例如下:1. 路径1的测试用例:valuek = 有效输入值,其中ki;value i = -999,
32、其中2i100;预期结果:基于k的正确平均值和总数。 注意:路径 1无法独立测试,必须作为路径4、5和6的一部分来测试。,2. 路径2的测试用例:value 1 = -999;预期结果:average = -999,其他都保持初始值。 3. 路径2的测试用例:试图处理101个或更多值;前100个数值应该是有效输入值;预期结果:前100个数的平均值,总数为100。 注意:路径 3也无法独立测试,必须作为路径4、5和6的一部分来测试。,4. 路径4的测试用例:value i = 有效输入值,其中i maximum,其中ki ;预期结果:基于k的正确平均值和总数。 6. 路径6的测试用例:value
33、 i = 有效输入值,其中i100;预期结果:基于i的正确平均值和总数。, 总结: 在测试过程中,执行每个测试用例并把实际输出结 果与预期结果相比较。一旦执行完所有测试用例, 就可以确保程序中所有语句都至少被执行了一次, 而且每个条件都分别取过true值和false值。 应该注意: 某些独立路径不能以独立的方式测试,也就是说, 程序的正常流程不能形成独立执行该路径所需要的 数据组合。在这种情况下,这些路径必须作为另一 个路径的一部分来测试。,例3. 使用基本路径测试方法,设计测试下面列出的伪码程序的测试用例。1: STARTINPUT(A, B, C, D)2: IF (A0) 3: AND
34、(BO)4: THEN X=A+B5: ELSE X=A-B6: END IF7: IF (CA)8: OR (DB)9: THEN Y=C-D10: ELSE Y=C+D11: END IF12: PRINT(X, Y)STOP,路径1:12346791112 路径2:1256791112 路径3:12356791112 路径4:123467891112 路径5:1234678101112,2. 条件测试 (1) 用条件测试技术设计出的测试用例,能够检查程序模块中包 含的逻辑条件。 (2) 逻辑条件可以是1个简单条件 or 复合条件。 简单条件. 可以是一个布尔变量或一个关系表达式;. 前可
35、加NOT算符; . 关系表达式的形式:E1 E2其中,E1和E2是算术表达式,而是下列算符之一:“”或“”。 复合条件. 由两个或多个简单条件、布尔算符和括弧组成;. 布尔算符有OR(“|”),AND(“&”)和NOT。, 条件成分的类型包括布尔算符、布尔变量、布尔括弧(括住简单条件或复合条件)、关系算符及算术表达式。 如果条件不正确,则至少条件的一个成分不正确。 因此,条件错误的类型如下:. 布尔算符错(布尔算符不正确,遗漏布尔算符或有多余的布尔算符). 布尔变量错. 布尔括弧错. 关系算符错. 算术表达式错,(3) 条件测试策略 1) 分支测试. 可能是最简单的条件测试策略,. 对于复合条
36、件 C来说,C的真分支和假分支以及C中的每个简单条件,都应该至少执行一次。 2) 域测试. 要求对一个关系表达式执行3个或4个测试。. 对于形式为 E1 E2 的关系表达式来说,需要 3 个测试分别使 E1 的值大于、等于或小于 E2 的值。,3) 包含n个变量的布尔表达式需要2n个(每个变量分别取真或假这两个可能值的组合数)测试。该策略仅在n很小时才是实用的。 4) BRO条件测试策略(branch and relational operator) 由K.C.Tai提出的; 前提条件:如果在条件中所有布尔变量和关系算符都只出现一次而且没有公共变量,则BRO测试保证能发现该条件中的分支错和关系
37、算符错。 测试原理:利用条件C的条件约束来设计测试用例。,例1:考虑条件C1: B1&B2,其中B1和B2是布尔变量。C1的条件约束为(D1, D2),按BRO测试策略要求,约束集(t, t) , (f, t) , (t, f)被C1的执行所覆盖。 例2:考虑条件C2: B1 & (E1=E2),其中B1是布尔变量,E1和E2是算术表达式。 C2的条件约束为(D1, D2),C2的约束集为:(t, =), (f, =), (t, ), (t, E2) & (E1=E2),其中E1、E2E3、E4是算术表达式。C3的条件约束为(D1, D2),C3的约束集为:(, =), (=, =), (,
38、), (, ),3. 循环测试 1)循环测试是一种白盒测试技术,它专注于测试循环结构的有效性。 2)在结构化的程序中通常只有3种循环,即简单循环、串接循环和嵌套循环。如图7.7所示。,1. 黑盒测试:又叫功能测试。 2. 黑盒测试着重测试软件的功能,并不能取代白盒测试。 3. 白盒测试技术主要应用在测试过程的早期,而黑盒测试主要用于测试过程的后期。 4. 应用黑盒测试技术,能够设计出满足下述标准的测试用例集:1) 所设计出的测试用例能够减少为达到合理测试所需要设计的测试用例的总数;2) 所设计出的测试用例能够告诉我们,是否存在某些类型的错误,而不是仅仅指出与特定测试相关的错误是否存在。,7.7
39、 黑盒测试技术,1. 等价划分技术把程序的输入域划分成若干个数据类,据此导出测试用例。 2. 等价划分法的目的:力图设计出能发现若干类程序错误的测试用例,从而减少必须设计的测试用例的数目。 3. 合理假设:如果把所有可能的输入数据划分成若干个等价类,则可合理地做出下述假定:每类中的一个典型值在测试中的作用与这一类中所有其他值的作用相同。 4. 结论:因此,可以从每个等价类中只取一组数据作为测试数据。这样选取的测试数据最有代表性,最可能发现程序中的错 误。,7.7.1 等价划分,5. 使用等价划分法设计测试方案的步骤: 1)需要划分输入数据的等价类;为此需要研究程序的功能说明,从而确定输入数据的
40、有效等价类和无效等价类。 2)设计一个新的测试方案以尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步骤直到所有有效等价类都被覆盖为止; 3)设计一个新的测试方案,使它覆盖一个而且只覆盖一个尚未被覆盖的无效等价类,重复这一步骤直到所有无效等价类都被覆盖为止。, 划分等价类的启发式规则:1)如果规定了输入值的范围,则可划分出一个有效的等价类(输入值在此范围内),两个无效的等价类(输入值小于最小值或大于最大值);2)如果规定了输入数据的个数,则类似地也可以划分出一个有效的等价类和两个无效的等价类;3)如果规定了输入数据的一组值,而且程序对不同输入值做不同处理,则每个允许的输入值是一个有效的等价类,此
41、外还有一个无效的等价类(任一个不允许的输入值);,4)如果规定了输入数据必须遵循的规则,则可以划分出一个有效的等价类(符合规则)和若干个无效的等价类(从各种不同角度违反规则); 5)如果规定了输入数据为整型,则可以划分出正整数、零和负整数等3个有效类; 6)如果程序的处理对象是表格,则应该使用空表,以及含一项或多项的表。 总结: 1)为了正确划分等价类,一要注意积累经验,二要正确分析被测程序的功能。 2)在划分无效的等价类时还必须考虑编译程序的检错功能。 3)这些启发式规则也同样适用于输出数据。,例1:设计下程序的测试方案,假设有一个把数字 串转变成整数的函数strtoint 。运行程序的计算
42、机字 长16位,用二进制补码表示整数。这个函数是用 Pascal语言编写的,它的说明如下: function strtoint (dstr: shortstr): integer; 函数的参数类型是 shortstr,它的说明是: type shortstr=array16 of char; 几点说明: 1)被处理的数字串是右对齐的; 2)如果数字串比6个字符短,则在它的左边补空格。 3)如果数字串是负的,则负号和最高位数字紧相邻(负号在最高位数字左边一位)。,4)考虑到pascal编译程序的固有的检错功能, 测试时不需要使用长度6的数组作为实在参数; 更不需要使用任何非字符数组类型的实在参数
43、。分析这个程序的规格说明,可划分出如下等价类: 有效输入的等价类有: 1) 16个数字字符组成的数字串(最高位数字不是零); 2) 最高位数字是零的数字串; 3) 最高位数字左邻是负号的数字串;, 无效输入的等价类有: (4) 空字符串(全是空格); (5) 左部填充的字符既不是零也不是空格; (6) 最高位数字右面由数字和空格混合组成; (7) 最高位数字右面由数字和其他字符混合组成; (8) 负号与最高位数字之间有空格; 合法输出的等价类有: (9) 在计算机能表示的最小负整数和零之间的负整数; (10) 零; (11) 在零和计算机能表示的最大正整数之间的正整数; 非法输出的等价类有:
44、(12) 比计算机能表示的最小负整数还小的负整数; (13) 比计算机能表示的最大正整数还大的正整数。,根据上面划分出的等价类,可以设计出下述测试方案: (1) 16个数字组成的数字串,输出是合法的正整数; 输入: 1 预期的输出:1 (2) 最高位数字是零的数字串,输出是合法的正整数; 输入:000001 预期的输出:1 (3) 负号与最高位数字紧相邻,输出是合法的负整数; 输入:-00001 预期的输出:-1 (4) 最高位数字是零,输出也是零; 输入:000000 预期的输出:0,(5) 太小的负整数; 输入:-47561 预期的输出:“错误无效输入” (6) 太大的负整数; 输入:13
45、2767 预期的输出:“错误无效输入” (7) 空字符串; 输入: 预期的输出:“错误没有数字” (8) 字符串左部既不是零也不是空格; 输入: 1 预期的输出:“错误填充错”,(9) 最高位数字后面有空格; 输入: 1 2 预期的输出:“错误无效输入” (10)最高位数字后面有其他字符; 输入: 12 预期的输出:“错误无效输入” (11)负号与最高位数字之间有空格; 输入:- 12 预期的输出:“错误负号位置错” 。,1. 经验表明,处理边界情况时程序最容易发生错误。 因此,设计使程序运行在边界情况附近的测试方案,暴露出程序错误的可能性更大一些。2. 使用边界值分析方法设计测试方案首先应该
46、确定边界情况;3. 通常输入等价类和输出等价类的边界,就是应该着重测试的程序边界情况;4. 按照边界值分析法,应该选取刚好等于、稍小于和稍大于等价类边界值的数据作为测试数据,而不是选取每个等价类内的典型值或任意值作为测试数据。,7.7.2 边界值分析,(12) 能输出刚好等于最小值的负整数; 输入:-32768 预期的输出:“-32768” (13) 能输出刚好等于最大值的正整数; 输入:32767 预期的输出:“32767” 原来用等价划分法设计出来的测试方案5最好改为: (14) 使输出刚刚小于最小的负整数; 输入:-32769 预期的输出:“错误无效输入” 原来的测试方案6最好改为: (
47、15) 使输出刚刚大于最大的正整数; 输入:32768 预期的输出:“错误无效输入”,7-5 某图书馆有一个使用CRT终端的信息检索系统,该系统有下列4个基本检索命令要求: (1) 设计测试数据以全面测试系统的正常操作; (2) 设计测试数据以测试系统的非正常操作。,答:(1)测试系统正常操作的测试数据1) 顺序执行下列3个命令:Browse( keyword )Select( L )Display( N ) 其中,keyword是正确的关键字;L是执行命令browse后屏幕上显示的约20个行号中的一个;N是执行命令S后列出的索引号中的一个。2)顺序执行下列2个命令: Find( name )
48、Display( N )其中,name是已经的作者姓名;N是执行命令find后列出的索引号中的一个。针对若干个不同的name重复执行上述命令序列。,(2)测试系统非正常操作的测试数据1)用过长的关键字作为命令browse的参数,例如:b(reliability software and hardware combined )预期的输出:系统截短过长的关键字,例如上述命令中的关键字可能被截短为:reliability software2)用不正确的关键字作为命令browse的参数,例如:b( aardvark) 预期的输出:显示出最接近的匹配结果,3)用比执行命令browse后列出的最大行号大1
49、的数作为命令s的参数,预期的输出:“命令s的参数不在行号列表中”4)用数字和标点符号作为命令browse和命令find的参数, 预期的输出:“参数类型错”,5)用字母字符作为命令select和命令display的参数,预期的输出:“参数类型错” 6)用0和负数作为命令select和命令display的参数,预期的输出:“参数类型错” 7)命令顺序错,例如,没执行命令b就执行命令s,或没执行命令s就执行命令d预期的输出:“命令顺序错” 8)命令语法错,例如,遗漏命令名b、s、d或f;或命令参数没用圆括号括起来预期的输出:“命令语法错” 9)命令参数空,例如,b()、s()、d()或f()预期的输出:系统提供默认参数或给出出错信息 10)使用拼错了的作者姓名作为参数f的参数预期的输出:“找不到这位作者的著作”。,