白盒测试用例的设计

张开发
2026/4/14 18:32:36 15 分钟阅读

分享文章

白盒测试用例的设计
点击文末小卡片免费获取软件测试全套资料资料在手涨薪更快正文语句覆盖每条语句至少执行一次。判定覆盖每个判定的所有可能结果至少出现一次。又称“分支覆盖”条件覆盖每个条件的所有可能结果至少执行一次。判定/条件覆盖一个判定中的每个条件的所有可能结果至少执行一次并且每个判断本身的所有可能结果至少执行一次。多重条件覆盖组合覆盖每个判定中的所有可能的条件结果的组合以及所有的入口点都至少执行一次。注意“可能”二字因为有些组合的情况难以生成。完全路径覆盖每条路径至少执行一次。基本路径覆盖根据流图计算环复杂度得到基本路径覆盖的用例数。分割后的完全路径覆盖每条路径至少执行一次每个条件的所有可能结果至少执行一次。覆盖程度路径覆盖 多重条件覆盖 判定/条件覆盖 条件覆盖 判定覆盖 语句覆盖1. 路径覆盖是覆盖率最高的。语句覆盖最弱。2. 满足多重条件覆盖准则的测试用例集同样满足判定覆盖准则、条件覆盖准则和判定/条件覆盖准则。任何一种覆盖方法都无法实现完全的测试。所以在实际的测试用例设计过程中根据需要将不同的覆盖方法组合起来使用以实现最佳的测试用例设计 。假设有一个待测试的小程序其Java源代码如下。使用以上白盒测试方法完成对小程序的测试用例设计。 public void foo (int a, int b, int x) { if(a1 b 0) { x x/a; } if (a2 || x1) { x x1; } }一、语句覆盖使用此准则测试上述小程序只需要遍历路径ace便将程序中的所有语句便都执行了一次。生成的用例及其遍历路径如下A2B0X4 ace缺点语句覆盖是“最弱的覆盖”它难以发现程序中的错误。①程序中存在一条x的值未发生改变的路径abd没有测试。②它无法发现判定的错误比如第一个判定条件也许应该是“或”而不是“与”。③无法发现条件的错误比如第二个判断中的条件X1也许事实上应该是X0。二、判定覆盖使用此准则测试小程序只需要涵盖路径ace和abd或涵盖路径acd和abe就可以使得两个判定为“真”和为“假”的分支都执行一次。如果选择后一种情况生成的用例及其遍历的路径如下A3B0X3 acdA2B1X1 abe我们仅有50%的可能性遍历到X值未发生改变的路径即只有我们选择涵盖路径ace和abd的情况而不是涵盖路径acd和abe时。对应的测试用例如下A2B0X2 aceA3B1X1 abd缺点这两组测试用例都存在同一个问题当判定由多个条件组合构成时它未必能发现每个条件的错误。如果第二个判定把条件X1错误的写成了X1我们设计的测试用例仍然无法找出这个错误。三、条件覆盖第一个判断的所有条件的可能取值情况是A1或A≤1B0或B≠0。第二个判断的所有条件可能的取值情况为A2或A≠2X1或X≤1。生成的用例及其遍历的路径如下所示A1B0X3 abeA2B1X1 abe缺点条件覆盖并不一定总能覆盖全部分支。测试用例虽然满足了条件覆盖准则但是只涵盖了程序的路径abe。但是条件覆盖还是要比判定覆盖强一些因为条件覆盖可能会使判断中各个条件的结果都取“真”或着取“假”而判定覆盖却做不到这一点。四、判定/条件覆盖判定/条件覆盖既要考虑到单个判定中每个条件的可能情况A1或A≤1B0或B≠0A2或A≠2X1或X≤1也要考虑到每个判定的可能情况路径ace和abd或路径acd和abe。用例及其遍历的路径如下所示A2B0X4 aceA1B1X1 abd缺点条件覆盖和判定/条件覆盖不一定会发现逻辑表达式中的错误。尽管看上去所有条件的所有结果似乎都执行到了但由于有些条件会屏蔽掉后面的条件并不一定能全部执行得到。例如上述测试用例①满足了条件A2后就不再执行对条件X1的判断测试用例②中不满足条件A1后就不再执行对条件B0的判断。五、多重条件覆盖满足多重条件覆盖准则的测试用例必须覆盖以下8种组合生成的测试用例以及它们遍历的路径和覆盖的组合如下A2B0X4 ace 覆盖组合15A2B1X1 abe 覆盖组合26A1B0X2 abe 覆盖组合37A1B1X1 abd 覆盖组合48缺点多重条件覆盖不一定能覆盖到每条路径路径acd就被遗漏掉了。六、路径覆盖为了满足路径覆盖必须首先确定具体的路径以及独立路径的个数。画出流程图。方法一我们通常采用控制流图的边弧序列和节点序列表示某一条具体路径。1弧a和弧b相乘表示为ab它表明路径是先经历弧a接着再经历弧b。2弧a和弧b相加表示为ab它表明两条弧是“或”的关系是并行的路段。在路径表达式中将所有弧均以数值1来代替再进行表达式的相乘和相加运算最后得到的数值即为该程序的 独立路径数 11*1*11*1 2*2 4。方法二与弧的计算方式类似还可以通过必经节点个数 i再找出必经节点下的路径数 w(i) 计算路径数。流程图中共有2个必经节点②⑥且先经历②再经历⑥没有并行的独立节点独立路径数 w(1)*...*w(i) 2*2 4。两种方法计算得到的路径数均为4条它们分别覆盖了abd、abe、acd、aceA1B0X1 abdA1B0X2 abeA3B0X1 acdA2B0X3 ace缺点1路径覆盖无法发现程序不符合设计规范的错误需要借助于黑盒测试的外部规格说明书。比如① 不一定发现路径本身的错误缺一条或多一条路径② 可能不会暴露数据敏感的错误比如计算两数之差小于某个值如果程序实现的是a-bc而不是|a-b|c那么当b-ac时则无法发现程序的逻辑错误。。所以建议先使用黑盒方法设计测试用例再使用白盒方法对用例进行补充。2路径覆盖不一定把所有的条件组合情况都覆盖。以上测试用例尽管从表面上看已经满足路径覆盖可是却无法发现程序当条件语句中的B0误写为B0时的错误即没有对B≠0的情况进行测试。另外第4个用例中由于A2第二个判定中的X1条件被忽略虽然覆盖了路径abd却无法发现X1误写为X2时的错误即没有对覆盖ace路径时X1的情况进行测试。3复杂程序的用例数呈指数级上升。假设一段程序有10条判断语句则i10 w(i)2独立路径数为2的10次方即1024则要为它设计1024个测试用例。七、完全路径覆盖完全路径即所有独立路径的集合非完全路径即所有独立路径集合的真子集。前面列出的独立路径集合并非完全路径因为前面的流程图中含有隐含路径。因此如果判断中的条件表达式是由一个或多个逻辑运算符 (OR, AND, NAND, NOR)连接的复合条件表达式则需要改为一系列只有单条件的嵌套的判断。细化后不含隐含路径的控制流图和流程图见下。独立路径数 (11*11*1)*(1*11*1*11*1) 3*3 9。或者必经节点有两个节点2.1和节点6.1独立路径数 w(1)*w(2) 3*3 9。路径一2.1→6.1→6.2→8路径二2.1→6.1→6.2→7→8路径三2.1→6.1→7→8路径四2.1→2.2→6.1→6.2→8路径五2.1→2.2→6.1→6.2→7→8路径六2.1→2.2→6.1→7→8路径七2.1→2.2→3→6.1→6.2→8路径八2.1→2.2→3→6.1→6.2→7→8路径九2.1→2.2→3→6.1→7→8由此要达到完全路径覆盖就需要设计9个测试用例去掉不可能的情况路径三因为A不可能同时满足A≤1A2两个条件仍然有8个用例。尽管在消除隐藏条件后解决了路径覆盖中的问题2但是完全路径覆盖的测试量比之前更加庞大。八、基本路径覆盖V(G) 6-52 3V(G) 21 3V(G) 2个闭合区域1个开放区域 3无论使用哪种方法计算都可确定3条独立的路径即基本路径覆盖的用例数。路径一②⑥⑧测试数据A1B0X1 abd路径二②③⑥⑧测试数据A3B0X1 acd路径三②⑥⑦⑧测试数据A1B0X2 abe思考为什么②⑥⑧②③⑥⑦⑧两个用例就可以将从②到⑧的路径全部覆盖基本路径覆盖计算的结果还需要三个用例我个人理解的原因是基本路径覆盖的一个测试用例一次只有一个变量因子。比如路径二相对路径一只有节点③发生了改变路径三相对路径一只有节点⑦发生了改变。而如果只有②⑥⑧②③⑥⑦⑧两个用例虽然覆盖到了全部路径但一次有两个因子③和⑦都发生了变化无法对单个条件变化的测试结果进行比对。V(G) 10-72 5V(G) 41 5V(G) 4个闭合区域1个开放区域 5无论使用哪种方法计算都可确定5条独立的路径即基本路径覆盖的用例数。路径一2.1→6.1→6.2→8测试数据A1B0X1 abid路径二2.1→2.2→6.1→6.2→8测试数据A3B1X1 afgid路径三2.1→2.2→3→6.1→6.2→8测试数据A3B0X1 afchid路径四2.1→6.1→7→8测试数据ABX abek路径五2.1→6.1→6.2→7→8测试数据A1B0X2 abijk设计测试数据时发现“路径四”abek不可能存在因为A不可能同时满足A≤1A2两个条件根据实际情况调整路径为afgek对应的测试数据为A2B1X1。缺点尽管基本路径覆盖用例已经比完全路径覆盖的用例少了许多但是当语句中有很多线性判定条件时仍然无法解决测试量指数上升的问题。九、分割后的完全路径覆盖如果消除隐藏路径后将程序在必经节点处割断分别对每一段程序进行完全路径覆盖的充分测试则即达到了完全路径覆盖的目的又能对必经节点中的每个条件都进行考量还大大减少了测试用例量。分割后的控制流图和流程图综合以上条件得到测试用例如下A1B0X1 aboid 输出A1B0X1A2B1X1 afgoek 输出A1B0X2A3B0X6 afchoijk 输出A1B0X2最终得到的用例数为3比程序被分割之前的所需用例数少了很多缓解了测试量过大的问题另一方面针对两个程序片段实现了完全路径覆盖解决了测试不足的问题。前面所提到的不一定覆盖所有条件组合情况下的BUG未测试到的B≠0X1的情况即将B0误写为B0X1误写为X2的错误将会被测试用例2和测试用例3发现。优点分割后的完全路径覆盖方法解决了前面所说的第2)、(3问题不仅对条件语句的每种情况都进行了考量还防止了测试用例呈指数级上升的可能解决了测试不足和测试量过大之间的矛盾。十、基本路径覆盖和分割后的完全路径覆盖用例对比基本路径用例(2)测试的是A1B≠0X≤1的情况在分割后的完全路径覆盖用例(2)中覆盖了A1B≠0的情况在分割后的完全路径覆盖用例(1)中覆盖了X≤1的情况。基本路径用例(3)测试的是A1B0X≤1的情况在分割后的完全路径覆盖用例(3)中覆盖了A1B0的情况在分割后的完全路径覆盖用例(1)中覆盖了X≤1的情况。基本路径用例(5)测试的是A≤1B值忽略X1的情况在分割后的完全路径覆盖用例(1)中覆盖了A≤1B值忽略在分割后的完全路径覆盖用例(3)中覆盖了X1的情况。结论基本路径覆盖对比起分割后的完全路径覆盖方法后者不但实现了路径覆盖还考虑到了条件语句的每种情况并且用例数比基本路径覆盖更为精简解决了完全路径覆盖和基本路径覆盖中复杂程序用例呈指数级上升的问题。最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。

更多文章