51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 759|回复: 0
打印 上一主题 下一主题

[原创] 测试用例设计方法逻辑覆盖之白盒测试

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-9-22 15:16:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
逻辑覆盖是以程序内部的逻辑结构为基础的设计用例的技术。
  根据覆盖目标的不同和覆盖源程序语句的详尽程度,逻辑覆盖又可分为:


  1. 语句覆盖(SC)


  2. 判定覆盖(DC)


  3. 条件覆盖(CC)


  4. 条件/判定覆盖(CC)


  5. 条件组合覆盖(MCC)


  6. 修正判定条件覆盖(MCDC)


  7. 点覆盖


  8. 边覆盖


  9. 路径覆盖


  几种逻辑覆盖标准发现错误的能力呈由弱至强的变化。


  下面我们来逐一举例详解:


  1语句覆盖(SC):

  语句覆盖是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每一个语句至少执行一次,其覆盖标准无法发现判定中逻辑运算的错误。

  我们看下面的被测试代码:


  int foo(int a, int b)


  {


  return a / b;


  }




  假如我们的测试人员编写如下测试案例:


  TeseCase: a = 10, b = 5



  测试人员的测试结果会告诉你,他的代码覆盖率达到了100%,并且所有测试案例都通过了。然而遗憾的是,我们的语句覆盖率达到了所谓的100%,但是却没有发现最简单的Bug,比如,当我让b=0时,



会抛出一个除零异常。

  简言之,语句覆盖,就是设计若干个测试用例,运行被测程序,使得每一可执行语句至少执行一次。这里的“若干个”,意味着使用测试用例越少越好。


  语句覆盖率的公式可以表示如下:



  语句覆盖率=可执行的语句总数/被评价到的语句数量 x 100%

  2判定覆盖(DC)


  判定覆盖是设计足够多的测试用例,使得程序中的每一个判断至少获得一次“真”和一次“假”,即使得程序流程图中的每一个真假分支至少被执行一次。

  但若程序中的判定是有几个条件联合构成时,它未必能发现每个条件的错误。


  例:


  int a,b;


  if(a || b)




  执行语句1


  else


  执行语句2



  要达到这段程序的判断覆盖,我们采用测试用例:

  1)a = true , b = false;


  2)a = false, b = false


  3条件覆盖(CC)


  条件覆盖是指选择足够的测试用例,使得运行这些测试用例时,判定中每个条件的所有可能结果至少出现一次,但未必能覆盖全部分支。

  例:


  int a,b;


  if(a || b)




  执行语句1


  else



  执行语句2


  要达到这段程序的条件覆盖,我们采用测试用例:


  1)a = true , b = false ;


  2)a = false, b = true


  4判定/条件覆盖(CDC)


  判定/条件覆盖是使判定中每个条件的所有可能结果至少出现一次,并且每个判定本身的所有可能结果也至少出现一次。

  例:


  int a,b;


  if(a || b)




  执行语句1


  else



  执行语句2


  要达到这段程序的判定/条件覆盖,我们采用测试用例:


  1)a = true , b = true;


  2)a = false, b = false




  5条件组合覆盖(MCC)


  选择足够的测试用例,使得每个判定中条件的各种可能组合都至少出现一次。显然,满足“条件组合覆盖”的测试用例是一定满足“判定覆盖”、“条件覆盖”和“判定/条件覆盖”的。


  例:

  int a,b;


  if(a || b)




  执行语句1


  else



  执行语句2


  要达到这段程序的判定/条件覆盖,我们采用测试用例:


  1)a = true , b = true;


  2)a = false, b = false


  3)a = true, b = false


  4)a = false, b = ture


  6修正判定条件覆盖(MC/DC)


  MC/DC首先要求实现条件覆盖、判定覆盖,在此基础上,对于每一个条件C,要求存在符合以下条件的两次计算:

  1)条件C所在判定内的所有条件,除条件C外,其他条件的取值完全相同;


  2)条件C的取值相反;


  3)判定的计算结果相反。


  核心意思是每个条件都要独立影响判定结果。为什么说“两次计算”,而不是“两个用例”呢?当循环中有判定时,一个用例下同一判定可能被计算多次,每次的条件值和判定值也可能不同,因此,一个



用例就可能完成循环中判定的MC/DC。

  MC/DC是条件组合覆盖的子集。条件组合覆盖要求覆盖判定中所有条件取值的所有可能组合,需要大量的测试用例,实用性较差。MC/DC具有条件组合覆盖的优势,同时大幅减少用例数。满足MC/DC



的用例数下界为条件数+1,上界为条件数的两倍,例如,判定中有三个条件,条件组合覆盖需要8个用例,而MC/DC需要的用例数为4至6个。如果判定中条件很多,用例数的差别将非常大,例如,判定中有


10个条件,条件组合覆盖需要1024个用例,而MC/DC只需要11至20个用例。

  下面是MC/DC的示例:


  代码:


  int func(BOOL A, BOOL B, BOOL C)


  {


  if(A && (B || C))


  return 1;


  return 0;


  }




  用例:




对于条件A,用例1和用例2,A取值相反,B和C相同,判定结果分别为1和0;


  对于条件B,用例1和用例3,B取值相反,A和C相同,判定结果分别为1和0;


  对于条件C,用例3和用例4,C取值相反,A和B相同,判定结果分别为0和1。


  9路径覆盖(PC)


  MC/DC被称为“最严格的标准”,但这种说法是将条件组合覆盖和路径覆盖排除在外为基础的。MC/DC显然不如条件组合覆盖严格,但是条件组合覆盖需要太多用例,实际应用中难以做到,所以排除,


那么,路径覆盖是否也难以做到?使用先进的工具,对于一般的代码,实现路径覆盖还是可能的。另外,路径代表了从函数入口到出口的所有可能的代码组合,这些组合会不会出问题?只有路径覆盖能发现,


这与MC/DC侧重于判定内的条件的组合关系是完全不同的。

  MC/DC与路径覆盖的侧重点不同,两者都有其优势和局限性,如果组合起来,优势互补,形成“MC/DC-路径覆盖”,就是真正意义上的“最严格的标准”了。


  有些程序,路径数量可能大得惊人,可用以下规则和方法减少路径数量:


  计算路径时,不考虑循环的次数,将循环结构视为循环体“至少执行一次”和“从不执行”两个分支;


  不考虑条件的计算结果只考虑判定的计算结果,条件间的组合关系由条件覆盖、C/DC和MC/DC负责;


  一个分支如果不可达,通过该分支的所有路径也不可达,可以让工具自动排除;


  当代码很复杂时,理想的处置方式是将部分代码独立为函数,如果做不到,可以让工具来模拟,即在逻辑结构图中,将部分代码临时屏蔽,被屏蔽的代码视为一个函数调用。交替屏蔽可以既减少路径数



量,又保证路径覆盖的效果。

  对于一般复杂度的代码,采用以上规则和方法后,路径数量和用例数量可以维持在一个现实可覆盖的的范围内。


  路径覆盖的主要缺陷是:不相关的逻辑块会组合出大量没有意义的路径。一个函数的路径,可能达到几万条甚至几百万条。如果路径超过100条,通常路径覆盖就没有意义了。对于一般企业来说,建议用



MC/DC作为统一的覆盖标准,只有特别关键的代码,才要求完成“MC/DC-路径覆盖”。

  路径覆盖要求设计足够多的测试用例,在[url=]白盒测试[/url]法中,覆盖程度最高的就是路径覆盖,因为其覆盖程序中所有可能的路径。


  对于比较简单的小程序来说,实现路径覆盖是可能的,但是如果程序中出现了多个判断和多个循环,可能的路径数目将会急剧增长,以致实现路径覆盖是几乎不可能的。






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-25 07:54 , Processed in 0.066436 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表