代码覆盖率是什么意思常见的几种方式浅谈

浮沉于世间,行流于指尖
代码覆盖率常见的几种方式浅谈
在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。于是乎,测试人员费尽心思设计案例覆盖代码。用代码覆盖率来衡量,有利也有有弊。本文我们就代码覆盖率展开讨论,也欢迎同学们踊跃评论。
首先,让我们先来了解一下所谓的“代码覆盖率”。我找来了所谓的定义:
代码覆盖率 = 代码的覆盖程度,一种度量方式。
上面简短精悍的文字非常准确的描述了代码覆盖率的含义。而代码覆盖程度的度量方式是有很多种的,这里介绍一下最常用的几种:
1. 语句覆盖(StatementCoverage)
又称行覆盖(LineCoverage),段覆盖(SegmentCoverage),基本块覆盖(BasicBlockCoverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。需要注意的是,单独一行的花括号{}
也常常被统计进去。语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。假如你的上司只要求你达到语句覆盖,那么你可以省下很多功夫,但是,换来的确实测试效果的不明显,很难更多地发现代码中的问题。
这里举一个不能再简单的例子,我们看下面的被测试代码:
int foo(int a, int b)
假如我们的测试人员编写如下测试案例:
TeseCase: a = 10, b = 5
测试人员的测试结果会告诉你,他的代码覆盖率达到了100%,并且所有测试案例都通过了。然而遗憾的是,我们的语句覆盖率达到了所谓的100%,但是却没有发现最简单的Bug,比如,当我让b=0时,会抛出一个除零异常。
正因如此,假如上面只要求测试人员语句覆盖率达到多少的话,测试人员只要钻钻空子,专门针对如何覆盖代码行编写测试案例,就很容易达到主管的要求。当然了,这同时说明了几个问题:
1.主管只使用语句覆盖率来考核测试人员本身就有问题。
2.测试人员的目的是为了测好代码,钻如此的空子是缺乏职业道德的。
3.是否应该采用更好的考核方式来考核测试人员的工作?
为了寻求更好的考核标准,我们必须先了解完代码覆盖率到底还有哪些,如果你的主管只知道语句覆盖,行覆盖,那么你应该主动向他介绍还有更多的覆盖方式。比如:
2. 判定覆盖(DecisionCoverage)
又称分支覆盖(BranchCoverage),所有边界覆盖(All-EdgesCoverage),基本路径覆盖(BasicPathCoverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到了。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。因此我们直接介绍第三种覆盖方式,然后和判定覆盖一起来对比,就明白两者是怎么回事了。
3. 条件覆盖(ConditionCoverage)
它度量判定中的每个子表达式结果true和false是否被测试到了。为了说明判定覆盖和条件覆盖的区别,我们来举一个例子,假如我们的被测代码如下:
int foo(int a, int b)
if (a & 10 || b & 10) //
return 0; //
return 1; //
设计判定覆盖案例时,我们只需要考虑判定结果为true和false两种情况,因此,我们设计如下的案例就能达到判定覆盖率100%:
TestCaes1: a = 5, b = 任意数字
覆盖了分支一
TestCaes2: a = 15, b = 15
覆盖了分支二
设计条件覆盖案例时,我们需要考虑判定中的每个条件表达式结果,为了覆盖率达到100%,我们设计了如下的案例:
TestCase1: a = 5, b = 5
trueTestCase4: a = 15, b = 15
false, false
通过上面的例子,我们应该很清楚了判定覆盖和条件覆盖的区别。需要特别注意的是:条件覆盖不是将判定中的每个条件表达式的结果进行排列组合,而是只要每个条件表达式的结果true和false测试到了就OK了。因此,我们可以这样推论:完全的条件覆盖并不能保证完全的判定覆盖。比如上面的例子,假如我设计的案例为:
TestCase1: a = 5, b = 15
TestCase1: a = 15, b = 5
false, true
我们看到,虽然我们完整的做到了条件覆盖,但是我们却没有做到完整的判定覆盖,我们只覆盖了分支一。上面的例子也可以看出,这两种覆盖方式看起来似乎都不咋滴。我们接下来看看第四种覆盖方式。
4. 路径覆盖(PathCoverage)
又称断言覆盖(PredicateCoverage)。它度量了是否函数的每一个分支都被执行了。 这句话也非常好理解,就是所有可能的分支都执行一遍,有多个分支嵌套时,需要对多个分支进行排列组合,可想而知,测试路径随着分支的数量指数级别增加。比如下面的测试代码中有两个判定分支:
int foo(int a, int b)
int nReturn = 0;
if (a & 10)
{// 分支一
nReturn +=
if (b & 10)
{// 分支二
nReturn +=
对上面的代码,我们分别针对我们前三种覆盖方式来设计测试案例:
a. 语句覆盖
TestCase a = 5, b = 5
nReturn = 11
语句覆盖率100%
b. 判定覆盖
TestCase1 a = 5,
nReturn = 11
TestCase2 a = 15, b = 15
nReturn = 0
判定覆盖率100%
c. 条件覆盖
TestCase1 a = 5,
nReturn = 1
TestCase2 a = 15, b = 5
nReturn = 10
条件覆盖率100%
我们看到,上面三种覆盖率结果看起来都很酷!都达到了100%!主管可能会非常的开心,但是,让我们再去仔细的看看,上面被测代码中,nReturn的结果一共有四种可能的返回值:0,1,10,11,而我们上面的针对每种覆盖率设计的测试案例只覆盖了部分返回值,因此,可以说使用上面任一覆盖方式,虽然覆盖率达到了100%,但是并没有测试完全。接下来我们来看看针对路径覆盖设计出来的测试案例:
TestCase1 a = 5,
nReturn = 0
TestCase2 a = 15,
nReturn = 1
TestCase3 a = 5,
nReturn = 10
TestCase4 a = 15,
nReturn = 11
路径覆盖率100%
太棒了!路径覆盖将所有可能的返回值都测试到了。这也正是它被很多人认为是“最强的覆盖”的原因了。
还有一些其他的覆盖方式,如:循环覆盖(LoopCoverage),它度量是否对循环体执行了零次,一次和多余一次循环。剩下一些其他覆盖方式就不介绍了。
通过上面的学习,我们再回头想想,覆盖率数据到底有多大意义。我总结了如下几个观点,欢迎大家讨论:
a. 覆盖率数据只能代表你测试过哪些代码,不能代表你是否测试好这些代码。(比如上面第一个除零Bug)
b. 不要过于相信覆盖率数据。
c. 不要只拿语句覆盖率(行覆盖率)来考核你的测试人员。
d. 路径覆盖率 & 判定覆盖 & 语句覆盖
e. 测试人员不能盲目追求代码覆盖率,而应该想办法设计更多更好的案例,哪怕多设计出来的案例对覆盖率一点影响也没有。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!讨论一下单元测试的方法,和代码覆盖率的统计方法
[问题点数:0分]
本版专家分:45
结帖率 100%
CSDN今日推荐
本版专家分:207
本版专家分:296
本版专家分:7884
本版专家分:1089
本版专家分:45
结帖率 100%
匿名用户不能发表回复!|
CSDN今日推荐您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
技术狂人:代码覆盖率浅谈.doc 3页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
你可能关注的文档:
··········
··········
技术狂人:代码覆盖率浅谈
在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。于是乎,测试人员费尽心思设计案例覆盖代码。用代码覆盖率来衡量,有利也有有弊。本文我们就代码覆盖率展开讨论,也欢迎同学们踊跃评论。 ??? 首先,让我们先来了解一下所谓的“代码覆盖率”。我找来了所谓的定义: ??? 代码覆盖率 = 代码的覆盖程度,一种度量方式。 ??? 上面简短精悍的文字非常准确的描述了代码覆盖率的含义。而代码覆盖程度的度量方式是有很多种的,这里介绍一下最常用的几种: ??? 1. 语句覆盖(StatementCoverage) ??? 又称行覆盖(LineCoverage),段覆盖(SegmentCoverage),基本块覆盖(BasicBlockCoverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。需要注意的是,单独一行的花括号{} 也常常被统计进去。语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。假如你的上司只要求你达到语句覆盖,那么你可以省下很多功夫,但是,换来的确实测试效果的不明显,很难更多地发现代码中的问题。 ??? 这里举一个不能再简单的例子,我们看下面的被测试代码: int foo(int a, int b) {
return a / } ??? 假如我们的测试人员编写如下测试案例: ??? TeseCase: a = 10, b = 5
??? 测试人员的测试结果会告诉你,他的代码覆盖率达到了100%,并且所有测试案例都通过了。然而遗憾的是,我们的语句覆盖率达到了所谓的100%,但是却没有发现最简单的Bug,比如,当我让b=0时,会抛出一个除零异常。 ??? 正因如此,假如上面只要求测试人员语句覆盖率达到多少的话,测试人员只要钻钻空子,专门针对如何覆盖代码行编写测试案例,就很容易达到主管的要求。当然了,这同时说明了几个问题: ??? 1.主管只使用语句覆盖率来考核测试人员本身就有问题。 ??? 2.测试人员的目的是为了测好代码,钻如此的空子是缺乏职业道德的。 ??? 3.是否应该采用更好的考核方式来考核测试人员的工作? ??? 为了寻求更好的考核标准,我们必须先了解完代码覆盖率到底还有哪些,如果你的主管只知道语句覆盖,行覆盖,那么你应该主动向他介绍还有更多的覆盖方式。比如: ??? 2. 判定覆盖(DecisionCoverage) ??? 又称分支覆盖(BranchCoverage),所有边界覆盖(All-EdgesCoverage),基本路径覆盖(BasicPathCoverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到了。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。因此我们直接介绍第三种覆盖方式,然后和判定覆盖一起来对比,就明白两者是怎么回事了。 ??? 3. 条件覆盖(ConditionCoverage) ??? 它度量判定中的每个子表达式结果true和false是否被测试到了。为了说明判定覆盖和条件覆盖的区别,我们来举一个例子,假如我们的被测代码如下: int foo(int a, int b)
if (a < 10 || b < 10) // 判定??
{ ??????? return 0; // 分支一?}??
{ ??????? return 1; // 分支二??
} } ??? 设计判定覆盖案例时,我们只需要考虑判定结果为true和false两种情况,因此,我们设计如下的案例就能达到判定覆盖率100%: ??? TestCaes1: a = 5, b = 任意数字 覆盖了分支一 ??? TestCaes2: a = 15, b = 15????????? 覆盖了分支二 ??? 设计条件覆盖案例时,我们需要考虑判定中的每个条件表达式结果,为了覆盖率达到100%,我们设计了如下的案例: ??? TestCase1: a = 5, b = 5?????? true, true ??? TestCase4: a = 15, b = 15?? false, false ??? 通过上面的例子,我们应该很清楚了判定覆盖和条件覆盖的区别。需要特别注意的是:条件覆盖不是将判定中的每个条件表达式的结果进行排列组合,而是只要每个条件表达式的结果true和false测试到了就
正在加载中,请稍后...记录工作学习中的一些经验。
AQtime代码覆盖率深度分析之一
前一篇介绍了Code Coverage的一些指标,那么如何比较简单的评价一款软件对这些指标的支持呢。由于公司的项目组选择AQtime这个工具,所以有机会能进行比较深入的体验一下。为了避免IDE自动产生的code,我们采用记事本来编写一个简单的C dll,用cl.exe进行编译,同时,写一些简单的测试案例。MyMath.cpp#include &iostream&
extern "C" _declspec(dllexport) int foo(int x, int y)
int result=0;
result+=1;
result+=10;
}该dll包含一个函数,共8行。有4个条件x&5, x≥5, y&5, y≥5四种条件,一共四条路径abd=0, abe=10, acd=1, ace=1,如下图所示:在vs2008的command line中,输入如下命令:cl.exe /EHsc /Zi /Od /LDd MyMath.cpp即可得到MyMath.dll, MyMath.pdb, VC90.pdb编写如下测试文件test.cpp(如果需要增加或者改动case,传入不同的参数即可)。#include &windows.h&
#include &iostream&
int main()
HINSTANCE hLib=LoadLibrary("MyMath.dll");
if(hLib!=0)
printf("MyMath.dll loaded.\n");
printf("MyMath.dll failed to load.\n");
typedef int (*FooPtr)(int x, int y);
FooPtr foo=(FooPtr)GetProcAddress(hLib,"foo");
int result=foo(1,10);
printf("The result is %d.\n",result);
FreeLibrary(hLib);
}同样,在vs2008命令行中,输入cl.exe /EHsc test.cpp即可得到test.exe测试程序。 新建一个AQtime code coverage工程,加入MyMath.dll作为目标文件,在运行参数中设置test.exe为Host Application。注意:由于我们是在vs2008的环境下用cl.exe进行编译,vc90.pdb是必须的,否则会对结果有影响。开始时我忽略了这个文件,结果发现竟然有20%的差别。 下面分别采用不同的测试案例,进行测试,看看AQtime会有什么输出,如下图所示:由上图可见,AQtime对语句覆盖(statemet coverage),函数覆盖(function coverage),循环覆盖(loop coverage)是支持比较好的,语句覆盖和函数覆盖在AQtime中对应的指标分别为Line Coverage和Routine Coverage;而对于条件覆盖(condition coverage),决策覆盖(decision coverage),条件/决策覆盖(condition/decision coverage)而言,其最终的summary中,并没有独立的指标项列出来。但是AQtime也对这些指标有个比较模糊/清晰的支持,如在Condition Coverage栏中,x=1, y=1 和x=10, y=10,一个的line coverage为100%,而另外一个为75%。显然,如果我们只有设计了第一个测试用例,很有可能就被迷惑;而在x=1, y=10和x=10, y=1中,每个case的line coverage都是87.5%,这就会提醒我们有些case漏掉了,而这两个case的合并结果为100%,的确是满足了条件覆盖的定义。同样的分析可以在Decision Coverage和Condition/Decision Coverage中体现出来。 另外,AQtime提供一个选项Mark partially executed lines as Partially executed(yellow)/Non-executed(red dot)/Completely executed(green dot)来如何统计或标识line coverage,选成Completely executed(green dot)可以相应的提高line coverage的百分比,但是,正如上一篇所提,我们不应该简单的追求一个代码覆盖率的数据,所以正确的做法应该是选择前面两项,这样才有利于我们发现问题,设计更有效的测试案例。 综上,AQtime是一个比较简单易用的代码测试覆盖率工具,其统计结果的方式为:根据debug info,如果是在VS2008或更高版本的的环境下编译,VCXX.PDB文件是必须的;其总行数是代码前面标有绿色和红色的行数之和,而不是实际我们在IDE中统计的行数;覆盖的行数是前面标有绿色或者黄色的行数之和(看如何设置);没有覆盖的行数是标有红色的行数之和;注:欢迎转载,但请注明出处,谢谢!
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!代码覆盖率
首先,我们需要明确一个问题,什么是代码覆盖率?基本上可以理解为测试过程中运行代码的行数与总行数的比率。代码覆盖程度的度量方式有很多种,比如语句覆盖,判定覆盖,条件覆盖,路经覆盖,这四种基本的覆盖方式测试能力从弱到强,那么问题是题目中的覆盖率100%是采用了哪种覆盖方式,即使采用了最强的
覆盖方式,测试人员就不能再发现缺陷了么?
软件缺陷,即为计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。所以我们测试代码的时候需要从很多角度出发,功能,性能,安全等。
(1)性能方面,常见的错误就是内存泄露,算法有待优化等,而这些往往是开发人员的思维死角。
(2)安全方面,一般是隐藏的漏洞,加密算法,容错能力等,有兴趣的朋友可以百度以下WebShell提权,典型的针对代码漏洞取得管理员权限。
(3)功能方面,比如集成测试,虽然模块功能正确,但集成后失效,其实就是接口存在缺陷。
随着测试人员对代码的理解,对系统的认识,知识的累积,会找到更多的角度测试,所以即使开发人员的代码覆盖率100%,我们要做的还有很多。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 代码覆盖率测试工具 的文章

 

随机推荐