白盒测试用例设计方法逻辑覆盖法

发表于:2022-9-19 09:24

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:半道出家的lv    来源:知乎

分享:
  逻辑覆盖是以程序内部的逻辑结构为基础的设计测试用例技术
  根据覆盖目标的不同和覆盖源程序语句的详尽程度,逻辑覆盖又可分为:
  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-路径覆盖”。
  路径覆盖要求设计足够多的测试用例,在白盒测试法中,覆盖程度最高的就是路径覆盖,因为其覆盖程序中所有可能的路径。
  对于比较简单的小程序来说,实现路径覆盖是可能的,但是如果程序中出现了多个判断和多个循环,可能的路径数目将会急剧增长,以致实现路径覆盖是几乎不可能的。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号