单元覆盖测试
  覆盖测试是衡量软件质量的一个重要的指标,是一种”白合”测试方法,覆盖的标准有逻辑覆盖,循环覆盖,基本路径覆盖。其中逻辑测试包括语句覆盖,判定覆盖,条件覆盖,判定/条件覆盖,条件组合覆盖和路径覆盖。
  覆盖测试必须拥有程序的规格说明书和程序清单,以程序的内部结构为清单设计测试用例。覆盖测试主要使用在具有高可靠性要求的软件领域(军工企业,航空航天软件,工业控制软件).覆盖测试需要借助一定的工具软件,工具软件具有的功能特点:
  分析软件内部接口,帮助定制覆盖策略及设计测试用例
  与适当的编译器结合,对被测软件实施自动插桩,以便在其运行过程中生成覆盖信息并收集这些覆盖信息
  根据收集的覆盖信息计算覆盖率(Coverage),帮助测试人员找到未被覆盖的软件部分,以改进测试用例,提高覆盖率
  对主流开发语言的支持,因为对不同的开发语言来说,测试工具的实现的方式和内容差别是较大的。目前测试工具主要支持的开发语言是:标准C,C++,Visual C++,Java等,
  进行动态覆盖测试的三项任务:1.设计测试用例;2.对被测代码进行插桩;3.收集覆盖信息并进行分析。
  2.1覆盖测试工具介绍
  xUnit基本不支持覆盖测试(白盒测试中重要的内容)。覆盖测试工具实现的技术方式和具体的语言是紧耦合的。不同语言使用的覆盖测试的策略是不一样的。实例如下:
  Java(EclEmma+JUnit,JCoverage)
  NET(NCover+NUnit)
  CppUnit框架很难提供覆盖测试的功能,c/c++测试覆盖测试是通过插桩实现的.C/C++覆盖测试工具:gcov
  2.2JUnit下的覆盖工具EclEmma
  时至今日,IT人士更加关注测试的重要性。 测试驱动开发(TDD)被证明是一种能有效提高软件质量的方法,测试优先原则,EclEmma2006年入围Eclipse Community Awards Winners 决赛
  2.2.1EclEmma
  Emma是Sourceforge上的开源项目,某种程度上,EclEmma是Emma的图形开发工具。
  Eclipse,OpenJDK,JUnit,Ant,CVS或者Subversion,Emma -- java开发成套开源的解决方案。
  Emma的同类产品:Coverlipse,Cobertura,Quilt,JCoverage.
  EclEmma的特点:快速的开发和测试周期,非常丰富覆盖信息分析以及非入侵方式。
  EclEmma:一个封装Emma覆盖工具的Eclipse的插件。Eclemma的官方地址:http://sourceforge.net/projects/eclemma
  EclEmma使用不同颜色标识的源代码测试的情况,绿色-完整执行,红色-根本没有执行,黄色-部分被执行,其视图能够分层显示代码的覆盖测试率。
  2.2.2EclEmma环境建立
  EclEmma的安装是就是Eclipse插件的安装,共有这样三种方式安装.
  1.Eclipse自身的Software Update机制.
  选中菜单栏中Help/Install New Softeware,在如下图中对话框中填入插件的站点的信息。

  本人是在Ubuntu12.04下使用eclipse的,如果是在windows下的话,具体操作可以参考[2]。
  缺点是:当安装了许多插件之后,eclipse的plugins中会充满各种旧的或废弃的插件,不便于更新和管理
  2.蛮力法安装
  将插件的压缩包解压,然后将其中的plugins和features与eclipse安装包中的同名文件夹合并,这样就可以在Eclipse中使用新插件。实际上第一个方法自动安装也是使用的这种方法,只不过由机器自动改成了手动。缺点同上。
 3. links文件
  首先从eclemma官方站点下载最新的eclemmaEclipse插件包:http://sourceforge.net/projects/eclemma/files/?source=navbar
  在eclipse安装的目录下新建一个links文件夹,将相应的插件(例如eclemma-2.2.0)包拷贝到links文件夹下,并在links下新建一个eclemma.link空白的文本,在起中写入:path=/usr/lib/eclipse/links/eclemma-2.2.0 。注意path=xxx是eclemma在系统中的绝对路径, 由于我使用的Linux系统,在windows下可能是D:\xxx\eclipse\links\eclemma-2.2.0。
  重新启动一下eclipse就可以看到eclemma被安装上的标志,最左边的就是Eclemma的图标。

  备注: 上面的步骤在windows上已经算是安装完成了,但是在Ubuntu下好像不太行,至少我自己的实践表明是这样的,Ubuntu下还要在加上两步:
  进入eclemma-2.2.0文件夹中,在其中建立一个eclipse文件夹并将eclemma目录下其他的文件移到 eclipse目录下
  进入eclipse目录,在其中建立一个空的.eclipseextension的隐藏文件(注意"."不可少),并为这个文件加上执行权限。具体的命令如下:
| cd /usr/lib/eclipse/links/eclemma-2.2.0/ sudo mkdir eclipse
 sudo mv * eclipse/
 cd eclipse/
 vi .eclipseextension
 chmod +x .eclipseextension
 | 
  注意命令中是否需要使用sudo提升权限视情况而定, 如果不是类似 /usr/lib这样的只有root权限才可以操作的目录的话,就不需要使用sudo。
  2.2.3 EclEmma的使用
  关于Eclemma的使用,网上一堆,不再赘述,推荐一篇文章:
  使用Eclemma进行覆盖测试:http://www.ibm.com/developerworks/cn/java/j-lo-eclemma/
  2.3C++的覆盖测试工具gcov
  gcov是GNU/GCC的工具组件,可以C/C++代码覆盖率的测试工具,使用便捷,不要配置,不是可视界面,只支持CLI命令行界面.如果要使用可视界面,使用Ggcov。
  2.3.1gcov环境
  gcov是gcc的内部工作组件。利用gcc内部的工具进行代码插桩。
  2.3.2gcov测试功能及使用流程
  grov的基本功能:可以查看测试时代码执行的覆盖率信息,支持函数覆盖,语句覆盖和分支覆盖等覆盖测试内容,帮助我们分析测试程序中的缺陷。使用该工具还可以查看程序在某个分析执行的频率,进而分析程序的性能。
  Gcc的覆盖测试工具gcov,gcov必须和gcc编译器联合使用(需要在程序中插桩,参考百度百科程序插桩的解释)。使用步骤:
  在编译时加上”-ftest-coverage-fprofile-arcs”,a.out(设置了-o选项就是输出的文件名)和.gcda文件;
  执行./a.out时,根据源程序的语句,条件,路径,边界等因素,以及设计好的输入测试用例数据 ,执行的信息保存到.gcno和.gcda文件中-->gcov-b xxx.c-->xxx.c.gcov(里面显示了每条语句执行的次数,没有执行的语法则以“####”标注)
  注意:使用gcov时,每次重新编译,统计数据都会清空,所以项目测试必须在确定的版本上进行。
  gcov的其他的选项命令可以查看gcov的在线文档(man gcov)
| /*Program: testgcov.c -- interpert the workflow of gcov */ #include<stdio.h>
 int main(){
 printf("Hello,World\n");
 }
 | 
 编译执行:gcc-o testgcov -ftest-coverage -fprofile-arcs testgcov.c
  ./testgcov--->执行程序,各种执行语句将会被写到testgcov.gcda和testgcov.gcno中
  gcov-b testgcov.c --->testgcov.c.gcov详细的覆盖信息
  testgcov.c.gcov 详细信息:
| -: 0:Source:testgcov.c-: 0:Graph:testgcov.gcno
 -: 0:Data:testgcov.gcda
 -: 0:Runs:1
 -: 0:Programs:1
 -: 1:/*Program: testgcov.c -- interpert the workflow of gcov */
 -: 2:#include<stdio.h>
 1: 3:int main(){
 1: 4: printf("Hello,World\n");
 1: 5:}
 | 
  注:gcov -b查看分支执行的频率,-f查看每个函数执行的情况。
  2.3.3gcov覆盖测试应用举例
| /*Program:autosell.c -- design the input test case and get the code coverage of program */#include<stdio.h>
 void welcome();
 void nochange(int num5coins);
 void getcoin(int *coin);
 void pushbutton(int *button);
 void process(int* coin,int* button,int* num5coins);
 int main(){
 int coin=0,button=0,num5coins=2;
 int i;
 for(i=0;i<10;++i){
 welcome();
 nochange(num5coins);
 getcoin(&coin);
 pushbutton(&button);
 process(&coin,&button,&num5coins);
 }
 return 0;
 }
 void welcome(){
 system("clear");//library function,which
 printf("welcome to this auto selling machine!\n\n");
 }
 void nochange(int num5coins){
 if(num5coins == 0)
 printf("No change now!\n");
 }
 void getcoin(int* coin){
 int flagredo;
 do{
 printf("Please pitch your coin(5-5角,10-1元):");
 scanf("%d",coin);
 if(*coin!=5 && *coin!=10){
 printf("Wrong coin!Return this coin.\n");
 flagredo=1;
 } else
 flagredo=0;
 }while(flagredo);
 }
 void pushbutton(int *button){
 int flagredo;
 do{
 printf("Please select your drink(1-orange juice,2-beer):");
 scanf("%d",button);
 if(*button!=1 && *button!=2){
 printf("Wrong input,Please re-select.\n");
 flagredo=1;
 } else
 flagredo=0;
 } while(flagredo);
 }
 void process(int* coin,int* button,int* num5coins){
 if(*coin == 10 && *num5coins ==0){
 printf("No change!\n");
 printf("Return 1 yuan coin.\n");
 } else {
 if(*coin == 10){
 if(*button ==1)
 printf("Please take your orange juice.\n");
 else
 printf("Please take you beer\n");
 (*num5coins)--;
 printf("Return 5 jiao coin.\n");
 }
 if(*coin == 5){
 if(*button ==1)
 printf("Please take your orange juice.\n");
 else
 printf("Please take you beer\n");
 (*num5coins)++;
 }
 }
 printf("\nPress Enter to continue");
 getchar();getchar();
  *coin =0;*button=0;
 }
 | 
 编译命令:gcc-o autosell -fprofile-arcs -ftest-coverage autosell.c
  执行程序(./autosell)随便输入一些测试用例:
  测试结果:
  显示总体覆盖率:gcov autosell.c
  File'autosell.c'
  Linesexecuted:94.55% of 55
  Creating'autosell.c.gcov'
  显示函数覆盖信息:gcov-f autosell.c
  Function'process'
  Linesexecuted:90.00% of 20
  Function'pushbutton'
  Linesexecuted:100.00% of 9
  Function'getcoin'
  Linesexecuted:100.00% of 9
  Function'nochange'
  Linesexecuted:75.00% of 4
  Function'welcome'
  Linesexecuted:100.00% of 4
  Function'main'
  Linesexecuted:100.00% of 9
  File'autosell.c'
  Linesexecuted:94.55% of 55
  Creating'autosell.c.gcov'
  显示分支信息:gcov-b autosell.c
  File'autosell.c'
  Linesexecuted:94.55% of 55
  Branchesexecuted:100.00% of 28
  Takenat least once:92.86% of 28
  Callsexecuted:87.50% of 24
  Creating'autosell.c.gcov'
  具体的autosell.c.gcov信息自行查看
  参考资料:
  [1]软件测试实验指导教程/蔡建平, 清华大学出版社, 2009.11
  [2]软件测试学习:测试覆盖率工具EclEmma安装与使用:http://liangruijun.blog.51cto.com/3061169/803473
  [3]使用Eclemma进行覆盖测试:http://www.ibm.com/developerworks/cn/java/j-lo-eclemma/
相关文章:
软件测试实验学习笔记系列4--CppUnit
软件测试实验学习笔记系列6--图形界面测试(GUI)