第十三讲白盒测试的测试方案设计测试方案与测试用例测试方案:测试目的+输入数据+期望结果测试用例:输入数据+期望结果设计测试方案的基本目标确定能够最大可能发现错误的测试用例测试技术与测试方案设计适用于白盒测试的技术:逻辑覆盖适用于黑盒测试的技术等价类划分边界值分析错误猜测法因果图法逻辑覆盖(LogicCoverage)1.语句覆盖2.判定覆盖3.条件覆盖4.判定/条件覆盖5.条件组合覆盖6.路径覆盖逻辑覆盖是以程序内部的逻辑结构为基础的设计测试用例的技术。它属白盒测试。PROCEXPA(A,B,X:REAL);BEGINIF(A1ANDB=0)THENX=X/A;IF(A=2ORX1)THENX=X+1;ENDL1(ace)ABAXA1021andandorABAABXA102101andandorandandABABXA20101andorandandL2(abd)=ABAX1021andandorABAX1021orandand=AAXBAX121021andandorandandAXBAX11021andorandandL3(abc)ABAX1021andandorABAX1021orandorA1andX1orB0andA2orB0andX1AXBABX110201andorandorandL4(acd)ABAXA1021andandorABAXA1021andandand1.语句覆盖语句覆盖就是设计若干个测试用例,运行被测程序,使得每一可执行语句至少执行一次。在图例中,正好所有的可执行语句都在路径L1上,所以选择路径L1设计测试用例,就可以覆盖所有的可执行语句。测试用例的设计格式如下【输入的(A,B,X),输出的(A,B,X)】为图例设计满足语句覆盖的测试用例:【(2,0,4),(2,0,3)】或【(3,0,9),(3,0,4)】覆盖a-c-e【L1】ABABXA20101andorandand?如果把AND误写成OR,这组测试用例有效否?2.判定覆盖判定覆盖就是设计若干个测试用例,运行被测程序,不仅每条语句至少执行一次,而且程序中每个判断的取真分支和取假分支至少经历一次。判定覆盖又称为分支覆盖。对于图例,如果选择路径L1和L2,就可得满足要求的测试用例:【(2,0,4),(2,0,3)】覆盖a-c-e【L1】【(1,1,1),(1,1,1)】覆盖a-b-d【L2】AXBAX11021andorandandABABXA20101andorandand如果选择路径L3和L4,还可得另一组可用的测试用例:【(2,1,1),(2,1,2)】覆盖a-b-e【L3】【(3,0,3),(3,1,1)】覆盖a-c-d【L4】AXBABX110201andorandorandABAXA1021andandand3.条件覆盖条件覆盖就是设计若干个测试用例,运行被测程序,使得程序中不仅每条语句至少执行一次,而且每个判断的每个条件的可能取值至少执行一次。在图例中,可事先对所有条件的取值加以标记。例如,对于第一个判断(A>1ANDB=0):条件A>1取真为,取假为条件B=0取真为,取假为对于第二个判断(A=2ORX>1):条件A=2取真为,取假为条件X>1取真为,取假为T3T3T4T4T1T1T2T2测试用例覆盖分支条件取值【(2,0,4),(2,0,3)】L1(a-c-e)【(1,0,1),(1,0,1)】L2(a-b-d)【(2,1,1),(2,1,2)】L3(a-b-e)或【(1,0,3),(1,0,4)】L3(a-b-e)【(2,1,1),(2,1,2)】L3(a-b-e)TTTT1234TTTT1234满足条件覆盖是否一定满足判定覆盖?第二组满足条件覆盖但不满足判定覆盖TTTT1234TTTT1234TTTT12344.判定/条件覆盖既满足判定覆盖又满足条件覆盖。即设计足够的测试用例,使得判断中每个条件的所有可能取值至少执行一次,同时每个判断的所有可能判定结果至少执行一次。例如,测试用例覆盖分支条件取值【(2,0,4),(2,0,3)】L1(a-c-e)【(1,1,1),(1,1,1)】L2(a-b-d)TTTT1234TTTT1234ABABXA20101andorandandAXBAX11021andorandand并不一定比条件覆盖或判定覆盖更强。原因?为避免条件之间的相互掩盖,可以分解为基本的判定,例如,ANDOR5.条件组合覆盖条件组合覆盖就是设计足够的测试用例,运行被测程序,使得每个判断的所有可能的条件取值组合至少执行一次。记①A>1,B=0作②A>1,B≠0作③A≯1,B=0作④A≯1,B≠0作TT12TT12TT12TT12⑤A=2,X>1作⑥A=2,X≯1作⑦A≠2,X>1作⑧A≠2,X≯1作测试用例覆盖条件覆盖组合【(2,0,4),(2,0,3)】(L1)①,⑤【(2,1,1),(2,1,2)】(L3)②,⑥【(1,0,3),(1,0,4)】(L3)③,⑦【(1,1,1),(1,1,1)】(L2)④,⑧TT34TT34TT34TT34TTTT1234TTTT1234TTTT1234TTTT12346.路径覆盖路径测试就是设计足够的测试用例,覆盖程序中所有可能的路径,即每条可能路径都至少执行一次。测试用例通过路径覆盖条件【(2,0,4),(2,0,3)】a-c-e(L1)【(1,1,1),(1,1,1)】a-b-d(L2)【(1,1,2),(1,1,3)】a-b-e(L3)【(3,0,3),(3,0,1)】a-c-d(L4)TTTT1234TTTT1234TTTT1234TTTT3412条件测试路径选择当程序中判定多于一个时,形成的分支结构可以分为两类:嵌套型分支结构和连锁型分支结构。对于嵌套型分支结构,若有n个判定语句,需要n+1个测试用例;对于连锁型分支结构,若有n个判定语句,需要有2n个测试用例,覆盖它的2n条路径。当n较大时将无法测试。条件测试注意的问题布尔算符错布尔变量错布尔括号错关系算符错算术表达式错循环测试路径选择循环分为4种不同类型:简单循环、连锁循环、嵌套循环和非结构循环。(1)简单循环①零次循环:从循环入口到出口②一次循环:检查循环初始值③二次循环:检查多次循环④m次循环:检查m多次循环⑤最大次数循环、比最大次数多一次、少一次的循环。①对最内层循环做简单循环的全部测试。所有其它层的循环变量置为最小值;②逐步外推,对其外面一层循环进行测试。测试时保持所有外层循环的循环变量取最小值,所有其它嵌套内层循环的循环变量取“典型”值。③反复进行,直到所有层循环测试完毕。④对全部各层循环同时取最小循环次数,或者同时取最大循环次数。可能的测试随嵌套层数的增加按照几何级数增长(2)嵌套循环(3)连锁循环如果各个循环互相独立,则可以用与简单循环相同的方法进行测试。但如果几个循环不是互相独立的,则需要使用测试嵌套循环的办法来处理。(4)非结构循环这一类循环应该使用结构化程序设计方法重新设计测试用例。基本路径测试基本路径测试方法把覆盖的路径数压缩到一定限度内,程序中的循环体最多只执行一次。它是在程序控制流图的基础上,分析控制构造的环路复杂性,导出基本可执行路径集合,设计测试用例的方法。设计出的测试用例要保证在测试中,程序的每一个可执行语句至少要执行一次。1.程序图(程序的控制流图)符号○为控制流图的一个结点,表示一个或多个无分支的PDL语句或源程序语句。箭头为边,表示控制流的方向。在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。如果判断中的条件表达式是由一个或多个逻辑运算符(OR,AND,NAND,NOR)连接的复合条件表达式,则需要改为一系列只有单个条件的嵌套的判断。2.程序的基本路径集程序的环路复杂性给出了程序基本路径集中的独立路径条数,这是确保程序中每个可执行语句至少执行一次所必需的测试用例数目的上界。从控制流图来看,一条独立路径是至少包含有一条在其它独立路径中从未有过的边的路径。例如,在图示的控制流图中,一组独立的路径是path1:1-11path2:1-2-3-4-5-10-1-11path3:1-2-3-6-8-9-10-1-11path4:1-2-3-6-7-9-10-1-11路径path1,path2,path3,path4组成了控制流图的一个基本路径集。基本路径示例一234576891计算它的环形复杂度V(G)=判定数+1=3+1=4求它的一组独立路径L1:1-9L2:1-2-7-8-1-9L3:1-2-3-4-6-8-1-9L4:1-2-3-5-6-8-1-93.导出测试用例导出测试用例,确保基本路径集中的每一条路径的执行。根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到—用逻辑覆盖方法。每个测试用例执行之后,与预期结果进行比较。如果所有测试用例都执行完毕,则可以确信程序中所有的可执行语句至少被执行了一次。必须注意,一些独立的路径(如例中的路径1),往往不是完全孤立的,有时它是程序正常的控制流的一部分,这时,这些路径的测试可以是另一条路径测试的一部分。基本路径测试的步骤1.源程序,程序流程图等→程序图2.计算环域复杂度N3.确定N个独立路径,即基本路径集4.设计测试数据基本路径示例二PROCEDUREAverage;/*计算100个以内的有效数(规定值域之内)的平均值;有效数的总和;有效数的个数。*/INTERFACERETURNSaverage,total.input,total.valid;INTERFACEACCEPTSvalue,minimum,maximum;TYPEvalue[1,100]ISSCALARARRAY;TYPEaverage,total.input,total.valid,value,minimum,maximumISSCALARARRAY;TYPEiISINTEGER;1:i=1;total.input=total.valid=0;sum=0;2,3:DOWHILEvalue[i]-999ANDtotal.input1004:total.input=total.input+1;5,6IFvalue[i]=minimumANDvalue[i]=maximum7:THENtotal.valid=total.valid+1;sum=sum+value[i];8:ENDIFi=i+1;9:ENDDO10:IFtotal.valid011:THENaverage=sum/total.valid;12:ELSEaverage=-99913:ENDIFENDaverage第一步:根据过程设计结果画出相应的程序图第二步:计算它的环形复杂度V(G)=判定数+1=5+1=6路径1:1-2-10-11-13路径2:1-2-10-12-13路径3:1-2-3-10-11-13路径4:1-2-3-4-5-8-9-2-…路径5:1-2-3-4-5-6-8-9-2-…路径6:1-2-3-4-5-6-7-8-9-2-…