关闭

单元测试和功能测试代码覆盖率实操详解(1)

发表于:2023-8-03 09:55

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

 作者:佚名    来源:知乎

  什么是代码覆盖率
  代码覆盖率就是运行测试之后,代码被覆盖到了多少,哪些代码跑了,哪些没有跑。根据运行测试手段不同,代码覆盖率分成了单元测试代码覆盖率、接口测试代码覆盖率和功能测试代码覆盖率。代码覆盖率最终的目的是找到那些没有被覆盖到的代码。
  但是没有覆盖到的代码就一定有问题吗?不一定有问题,但要知道,一个完整的测试运行之后,有哪些代码没有跑到。这些代码有可能是有问题的,也有可能是没有问题的,有可能是冗余的,也有可能架构设计有问题,都有可能。我们不能说它是不好的代码,但至少是有问题的代码,这是我们做代码覆盖率的目的,而非去度量某一个质量指标。
  做代码覆盖率比较容易犯的一个误区,会觉得代码覆盖率到达了80%就说明没有问题。就像做性能测试的时候,TPS上到了多少,CPU使用率到达了多少就一定怎样。我们经常说,抓一些数据的把手是一个很不好的习惯,仅仅是找一些指标让自己心里变得舒服而已。比如说指定CPU使用率到达75%就一定怎样了,拿着这根线去卡一切,这样很多事就变得简单了,但实际工作中并非如此简单。
  上面这张图的意思是发现没有被覆盖到的代码,而不是简单的做一些质量的标准。代码覆盖率可以帮助我们: 1、分析未覆盖部分的代码,从而反推前期测试设计是否充分,没有覆盖到的代码是否是测试设计的盲点,为什么没有考虑到?是需求/设计不够清晰,测试设计的理解有误,之后进行补充测试用例设计。 2、检测出程序中的废代码,可以逆向反推在代码设计中思维混乱点,提醒设计/开发人员理清代码逻辑关系,提升代码质量。 3、代码覆盖率高不能说明代码质量高,但是反过来看,代码覆盖率低,代码质量不会高到哪里去,可以作为测试自我审视的重要工具之一。
  代码覆盖率统计指标
  我们可以从多个维度去考虑代码的覆盖情况,我们先来看第一个纬度,语句的覆盖。
  语句覆盖(StatementCoverage)
  语句覆盖(StatementCoverage)又称行覆盖(LineCoverage),度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,不包括头文件声明,代码注释,空行等。只统计能够执行的代码被执行了多少行。简单来说,就是这行代码只要被覆盖到了就是1,没有被覆盖到就是2。
  我们先来看上面这段代码,这里有价值的语句一共有3条语句:判断语句是一条,return 0是一条,return 1是一条。很多代码覆盖率会认定else不算,因为它就是一个关键字,实际上没有什么语句的价值。
  如果每一行都执行到了,行覆盖率就是1,总共3行,3行都执行到了,行覆盖率就是100%。稍微有点代码常识的人看到这里就能看出问题了,如果这个if语句我确实执行到了,但是它明显地有判断条件。
  如果第一个判断条件执行了,就能判断出这个语句的真假,后面的判断条件不执行了,继续往下走。这个语句确实叫执行了,true/ false 都没有完全覆盖到而已,所以我们说行覆盖是最弱的代码覆盖。
  语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。
  判定覆盖(DecisionCoverage)
  除了行覆盖、语句覆盖之外,还有判定覆盖,后面我们有详细的例子。什么叫判定覆盖?判定覆盖也叫分支覆盖(BranchCoverage),度量程序中每一个判定的分支是否都被测试到了。
  这很好理解,比如我们刚才的例子里有一个if语句,行覆盖就是一行行往下走,判定覆盖是指有分支的语句,每一个语句是否都被走到了。我们再来一起看一下这个例子。
  这个例子完整地有if有 else,所以行一旦覆盖成功了,三句都走完了,那么分支覆盖肯定也是百分之百走完,也是成功的,因为if走了,else也走了。
  我们试想一下,如果把下面的else盖住的话,没有这个else,只有if,如果语句覆盖里面的if走到了,return走到了,行覆盖率是百分之百,但是else的条件并没有测到,这个时候只覆盖到了if为true的情况,没有覆盖到else分支,虽然else分支里面没有代码。
  这个例子就说明判定覆盖和行覆盖还是有本质区别的。
  条件覆盖(ConditionCoverage)
  它度量判定中的每个子表达式结果true和false是否被测试到了。为了说明判定覆盖和条件覆盖的区别,我们来举一个例子,假如被测代码如下:
  在刚才的例子里,如果if、else都走到了,那么分支覆盖肯定也是百分之百,但是条件覆盖不一定是百分之百。if整体为true,确实走到了,if整体为false,也就是else,确实也走到了,对于if判断语句来说,两个分支确实都走到了。
  但这里面还有一个问题,if后面是有两个判定条件的,稍微有点代码常识的朋友都知道,不管什么语言,都有逻辑判断短路的问题。两个and判断,如果有一个and判断为false了,后面就不会判断了,所以那个就不走了,不管走不走,并没有覆盖到两个并列条件,两个子条件都为true或都为false的情况并没有走到。
  整体的判断语句走到了,但是里面两个具体的分支判断条件分别的true、false没有走到。这个时候分支覆盖率是百分之百了,但是条件覆盖率并不是百分之百。
  路径覆盖(PathCoverage)
  它度量了是否函数的每一个分支都被执行了。有多个分支嵌套时,需要对多个分支进行排列组合。因为现在只有一个if条件,所以不好看路径。举个例子,比如两个判定条件,两个if,只覆盖了第一个if判定条件的true和false以及第二个判定条件的true和false,但是两个并没有分别来走。
  比如第一个是true,第二个是false,或者第一个是false,第二个是true的这种交叉情况。也就是没有把包含所有的if、else条件的整体当成一个完整的路径去处理,这个路径就有多种组合了。这就是路径覆盖。
  下面再通过一个小例子去详细解说一下。
  上面是一个java的语句,一个foo函数,有a、b两个整型,一个if条件,if条件里面有两个小的条件。接下来有一个else分支语句,最后有一个return语句。有一组判断,两个分支,三个语句(不算定义的话)。
  TestCaes1: a=5, b=任意数字 
  当a=5的时候,a<10这个条件成立,对于逻辑或来说,前面的条件为真,后面的条件就不用判断了,必然是为真的。所以我给出的第一组测试用例,当a=5, b=任意数字时,它都会走到分支一,我们再给一个值。
  TestCaes2: a = 15,b = 15 
  当a=15时,a<10不成立,进而去判断第二个条件,当b=15,b<10也不成立的时候,会走到else这里,这样也覆盖了分支二。
  语句覆盖100%,分支覆盖也是100%,但是里面小条件的true和false并没有很完整地被覆盖。a<10为true、为false和b<10为true、为false的情况没有分别覆盖,因为逻辑短路的原因,所以你不能让它短路。
  完全的条件覆盖:
  TestCase1: a = 5,b = 任意数字 ture X
  TestCase2: a = 15, b = 5 false, true
  TestCase2: a = 15, b = 15 false, false
  第一条,先让a=5,b=任意数字,这个时候a<10这个条件为true的情况已经被覆盖。接下来通过a = 15, b = 5和a = 15, b = 15 这两组数据,让a<10这个条件为false时,b<10这个条件的true和false,都覆盖到了。
  在这个逻辑或的条件中,每个分支的true和false都覆盖到了,这个时候才完成了我们所说的条件覆盖。
  下面我们再一起来看一个例子。
  对于这样两个并列的if条件来说,怎么来写语句测试用例以做到语句覆盖率100%、判定覆盖率100%、条件覆盖率100%、路径覆盖率100%。
  TestCase a = 5, b = 5 nReturn = 11
  语句覆盖率100%
  TestCase1 a = 5, b = 5 nReturn = 11
  TestCase2 a = 15, b = 15 nReturn = 0
  判定覆盖率100% 条件覆盖率100%
  TestCase1 a = 5, b = 5 nReturn = 0
  TestCase2 a = 15, b = 5 nReturn = 1
  TestCase3 a = 5, b = 15 nReturn = 10
  TestCase4 a = 15, b = 15 nReturn = 11
  路径覆盖率100%
  从这里可以看出,如果想达到路径覆盖率100%的话,测试用例一定是比前三种要多的。所以我们最终得出的结论是:路径覆盖率 > 判定(分支)覆盖 > 语句覆盖。
  下面的内容就进入到我们本次分享的重点,代码覆盖率的工具。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号