代码覆盖率分析
来源:互联网 发布:js属性的nodetype 编辑:程序博客网 时间:2024/05/16 10:04
无论是单元测试、API测试还是功能性测试,最终都是调用了产品的代码;如何评价这些测试的效率,是否真正全部或者大部分覆盖了产品的代码,这个时候,代码覆盖率(code coverage)就是一个比较有价值的参考指标了。
通常,代码覆盖率用在如下几个方面
- 找出程序中没有被测试代码执行到的地方;
- 增加新的测试代码,以提高代码覆盖率;
- 分析测试代码的效率,以便设计出更有效的测试代码或测试用例
代码覆盖率常用的指标
语句覆盖(statement coverage):语句覆盖是指程序的每一行代码是否都被覆盖到;语句覆盖是最常用的一种代码覆盖率指标,也非常简单。但是对一些控制结构的代码而言,它不能真正表示是否完全覆盖到,如下代码:
int* p=NULL;if(condition) p=&variable;*p=123;
在以上代码中,如果condition为true,这时,语句覆盖率就为100%。而其实当condtion为false,会导致空指针被赋值的运行时错误。
决策覆盖(decision coverage):决策覆盖是指在控制结构的代码块,如if, while中的整个bool表达式是否在false和true条件下,各被执行一次。决策覆盖不考虑组成该条件表达式的各个子条件是否被完全覆盖到。于是,通常对于c/c++/java语言,由于short circuit operators,对于一个由多个条件以与关系组成的一个条件表达式,当出现第一个条件被检测为false时,其后所有的条件都不会被执行了。考虑一下代码:
if(condition1 && (condition2 || function1())) statement1;else statement2;
在condtion1为false和conditon1为true,condition2为true,其决策覆盖率为100%,而function1中的代码从未被执行。决策覆盖也叫分支覆盖(branch coverage)。
条件覆盖(condition coverage):条件覆盖是指每个条件都必须有true和false的情况,这里一个条件是一个逻辑操作符的操作数,但是不含该逻辑操作符。注意和决策覆盖的区别,如
bool f(bool e){ return false; }bool a[2]={false, false};if(f(a&&b)) ...if(a[int(a&&b)]) ...if((a&&b)?false:false) ...
该代码块的3个if条件中,一共包含2个条件a,b;共四种情况a=true, a=false, b=true, b=false;我们只需取a,b分别为true和false的组合(a=true, b=false和a=false, b=true)即可使条件覆盖为100%;而实际上,无论a,b取什么值,3个if语句的分支始终都返回false。
多重条件覆盖(multiple condition coverage):多重条件覆盖是指各个条件的每个可能的组合是否被检查到。多重条件覆盖中的各个条件组合是一种排列关系,而不是组合。通常多重条件覆盖的测试案例设计都非常复杂,因为在考虑到各个条件之间的排列关系时,其数量本身就多,而且还要考虑关系之间的相互影响,剔除无效的排列。
条件/决策覆盖(condition/decision coverage):条件决策覆盖是条件覆盖和决策覆盖的联合运算,它具有比多重条件覆盖简单的优势,同时又没有条件覆盖和决策覆盖的缺点。
改进的条件/决策覆盖(modified condition/decision coverage):其定义是程序中的每个入口和出口都至少被调用一次,一个决策的每个条件都至少有一次所有可能的输出,程序中的每个决策都至少有一次所有可能的输出,一个决策中的每个条件都能独立的影响该决策的输出(该条件改变,而其他条件保持不变)。
路径覆盖(path coverage):路径决策指示函数中的每个可能的路径是否被执行到。一条路径是一个唯一的从函数入口到出口的分支序列。路径覆盖通常能比较彻底的进行测试,但是它也有两个非常严重的缺陷:其一,路径的数量是分支数量的几何级数。例如,一个具有10个if语句的函数,需要1024个路径测试;而我们再加一条if语句,则有2048个路径需要测试。其次,由于数据相互关系,有些路径是不可能被测试到的,如:
if(success) statement1;statement2;if(success) statement3;
这段代码包含4条路径。而实际上,只有2条是可行的,success=false和success=true。
代码覆盖率的其他指标
其他代码覆盖率的指标还有函数覆盖率(function coverage);调用覆盖率(call coverage);循环覆盖率(loop coverage)等等。
代码覆盖率之间的关系
- 决策覆盖通常是包含语句覆盖的,因为每个分支的执行必然需要每个语句的执行。但是,如果函数的控制流被throw,abort等语句打断,那么该规则就不适用了。
- 条件/决策覆盖包含条件覆盖和决策覆盖。
- 路径覆盖包含决策覆盖。
该如何利用代码覆盖率的数据
通常,我们都希望用较少的时间设计出高效的测试案例。简单的来说,高效的测试案例就是能尽可能多的发现程序中的问题。测试所花的时间、覆盖率和检测出的时间可参考下面的图表:
即便代码覆盖率为100%,我们只能说程序中的每行代码都被执行到了。但是如果我们一定要有一个定量的指标,可参考下表:
Coverage typewithout dependency injectionwith dependency injectionFunction90%99%Line75%95%ref: http://blogs.msdn.com/b/cellfish/archive/2008/06/16/code-coverage.aspx
Dependency Injection(DI)是一种设计模式,即把一个对象引入到一个类中,而不是依靠类来创建对象本身。具体可参考:http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
值得注意的是:
- 不要一味的追求数据,为了提高代码测试覆盖率而去设计测试案例;
- 而要以代码测试覆盖率为参考,让它来帮助我们设计更加有意义,高效的测试用例;
如果你或者你的老板一定要一个非常漂亮的数字,或者你用它来考量测试人员的绩效,那么对于.net平台上的程序,微软有一个叫Pex的工具,可以帮助你生成高代码覆盖率的测试案例。具体可参考:
http://research.microsoft.com/en-us/projects/pex/
注:本文大部分参考Code Coverage Analysis,欢迎转载,但请注明出处。谢谢。
- PHP 代码覆盖率分析
- 代码覆盖率分析
- 代码覆盖率分析
- 代码覆盖率分析
- 代码覆盖率分析(gcov)
- AQtime代码覆盖率深度分析之一
- AQtime代码覆盖率深度分析之二
- Jacoco & Cobertura代码覆盖率分析对比
- 代码覆盖率
- 代码覆盖率
- 代码覆盖率
- 代码覆盖率
- Verilog代码验证的全面性与代码覆盖率分析
- gcov测试代码覆盖率及分析代码性能
- Linux下gcov和lcov代码覆盖率分析(C/C++覆盖率在NGINX测试中的应用)
- PHPUnit袖珍指南 第十章 代码覆盖率分析
- gcov和lcov对linux c++分析代码覆盖率
- Linux平台代码覆盖率测试工具GCOV相关文件分析
- Asp.net Excel批量导入数据到SqlServer数据库
- 【转】用汇编实现原子操作
- Spring Security配置
- 文本框检查
- 分享HTML相关的两个地址
- 代码覆盖率分析
- Balsaming Mockups - Efficiency & Cute Handwriting Design
- CoNLL大会内容
- php连接hive执行sql查询
- initrd.img和vmlinux的作用分别是什么?
- VS 2010 Add-in 开发
- Oracle数据库导入导出方法的个人总结
- chow 的用法
- Sql2000的备份文件导入到sql2005中