内容


PureCoverage 报表脚本:最大限度利用您的覆盖率数据

Comments

illustration大多数的软件开发员和测试员已经知道,测量测试的代码覆盖率,是一个不错的注意。甚至有许多人具有特定的目标,以测试特定比例的代码。但是一旦您收集了所有的覆盖率数据,您可以对它们做些什么呢?“X 百分覆盖率”的单个总体性测量,只是 PureCoverage 收集数据的一小部分。本篇文章将会探讨 PureCoverage 可以生成的报告,它能帮助您去最大程度的利用覆盖率数据,并手把手的教会您怎样去创建它们。

PureCoverage 报告

该 PureCoverage 报告能向您提供四种类型的报告:

  1. Coverage 报告测量整个项目的覆盖率,并分析哪些代码已经被分析过了,哪些没有。
  2. Difference 报告是关注已经更改代码的覆盖率报告。
  3. Test Coverage 报告识别了需要运行,以涵盖给定的更改后的源文件集合的测试。直接让报告生成脚本执行测试也是可能的。
  4. Utility 报告格式化覆盖率数据,以便共享诸如 spreadsheets 以及 Web 浏览器之类的工具。

通过使用这些特定的报告,使用这些代码覆盖率数据,以探测许多团队可能会碰到的一些共同类型的问题。例如:

  • Defect 逃逸,由未测试代码造成。如果您不知道什么代码未测试的话,那么您就不能添加测试以弥补这个空白。覆盖率数据会告诉您,哪些数据需要进行额外的测试。
  • Regressions。当日程安排压力让在检查每一个代码更改之前运行完整的测试集变得不现实时,PureCoverage 通过识别哪些可利用测试将会更佳的测试更改的函数,可以帮助开发员降低引入降级的风险。
  • Redundant 测试。为了降低丢失添加的任务的风险,可以进行冗余测试废物资源。覆盖率数据可以帮助识别能被遗弃的无用数据。
  • 覆盖侵蚀。添加新特性要比添加新测试快得多。在一个已经存在的特性内,在测试内没有相应更新的前提下,添加或者更改代码也是常见的。结果就是代码覆盖率降低了产品的生命。覆盖率数据能够迅速的发现这种情况,所以它能够被校正。
  • Schedule 变动,由质量问题造成。如果覆盖率是通过产品的整个生命周期内测量的话,估计剩余需要做的测试的量会更加容易,反过来这又让日程表变得可以预测。

报表脚本以及怎样去使用它们

我们将会讨论提供的每一个 PureCoverage 报表脚本,以及怎样去使用它。在下面的例子中,假设您已经使用 PureCoverage 运行一系列的测试,以生成一个或者多个 .pcv 覆盖率文件。表 1 总结了可用的脚本 。

表 1: PureCoverage 提供的报表脚本

报告名

脚本

描述
覆盖率总结报告
pc_summary生成一个总体总结
低覆盖率报告
pc_below带有低覆盖率的报告模型
低覆盖率邮件报告pc_email将报告寄给修改不足量覆盖文件的用户
Spreadsheet 报告pc_ssheet以 spreadsheet 格式生成一个总结
Differences 报告pc_diff为已经更改的覆盖率列出文件
构建差异总结报告pc_build_diff从程序的两个构筑里比较 PureCoverage 数据
注释源报告pc_annotate生成一个注释的源文本文件
注释差异报告pc_covdiff为修改的源代码注释差异的输出
Selected 测试报告pc_select识别需要进行已修改源代码的测试集
自动化选择的测试报告和执行文件pc_find_tests检查源控制系统以找出更改的文件和函数,使用 pc_选择以识别运行的测试,并报表测试或者执行测试的列表,并报告它们的结果(需求编辑)。
PureCoverage HTML 报告
purecovweb.pl一个 Perl 脚本会将一个 PureCoverage 文本数据文件,转化成一系列的 HTML 文件 

覆盖率报告

覆盖率报告是大多数 PureCoverage 报告的基础,它们呈现的是覆盖率数据本身,而不是任何的分析数据。覆盖率报告可以回答诸如“我的测试覆盖我的源代码的情况如何?”以及“需要进一步测试哪一种类型的模型?”之类的问题。PureCoverage 提供了三种报告覆盖率的脚本 :

  • pc_summary 生成一种覆盖率总结报告 
  • pc_below 生成一种列出所有低覆盖率模型的报告 
  • pc_email 提供了一种带有低覆盖率以及对所有模型修改者的电子邮件

覆盖率总结报告:

pc_总结脚本生成了一个覆盖率报告,它与和 PureCoverage Viewer 相似的方式显示。该脚本以文件中使用的列出的号码以及函数的覆盖率百分比,来生成了对整体的总结,以及在每个文件和函数中的号码以及百分比覆盖率。

图 1 显示了一个简单的 PureCoverage 覆盖率总结报告。该报告显示了测试期间执行“main.c”(一个范例源文件)的覆盖率的总结。被标注“**main.c total**”的行报告说已经执行了 33% 的函数以及 46% 的代码行;例如,每九个函数中都有三个,每 32 行代码行中有 15 行被使用过了。在 "**main.c total**" 下面的行中,进一步列出了具体的以上数据:提供了“main.c”中为每一个函数负责的代码行覆盖的信息。

PureCoverage Summary Report Sun Mar 9 14:50:31 IST 2008 Page 1
File: ./../../include/main.c
函数名字
使用过的函数
使用过的函数
所占百分比(%)
访问的
次数
未使用的
代码行
使用过的
代码行
使用过的代码行
所占百分比(%)
** main.c total **333%171546%
DoubleCPULimit0200%
DoubleDataLimit0200%
DoubleWallClockLimit0200%
install_handler106100%
main105100%
real_dummy0200%
real_dummy_ptr0200%
setup_catch_runaways104100%
sig_handler0700%

图 1:pc 总结产生的覆盖率总结报告

执行 pc 总结的语法是:

%pc_summary [-file=<name>...]  [<prog.pcv...>]

其中文件 <prog>.pcv 就是 PureCoverage 数据文件。选项 -file=<name> 指定了哪一个文件将会出现在总结中。默认条件下,报告包括了 .pcv 文件参考的所有的源文件。

范例:pc_summary -file=main.c test1.pcv test2.pcv test3.pcv

低覆盖率报告:

下边的 pc 生成了低覆盖率的报告。该报告列出了哪一个源文件的代码行覆盖率百分比,低于特定的最低阀值水平。每个特定模型的覆盖率也许会很低,这是因为它们没有经过足够的测试来锻炼它们。在有些情况下,开始时很好的模型覆盖率,会由于覆盖率退化而在时间因素上出现问题;例如,添加的新模型。在没有对其进行足够新的测试的情况下就是这样。图 2 显示了一个列出了源文件的覆盖率报告,它还带有 myprog.pcv 中不超过 75% 覆盖率的覆盖率数据。左边的数据显示了每一个源文件中的代码行覆盖率的总体百分比。

# pc_below -percent=75 all_tests.pcv
18 /usr/p/QE/tests/test1/foo2.c
33 /usr/p/QE/tests/test1/test.c
18 /usr/p/QE/tests/test2/subdir/foo3.c
46 ./include/main.c

图 2:由下面 pc 产生的低覆盖率报告

执行下面 pc 的语法是:

%pc_below [-percent=<nn>][<prog.pcv...>]

文件 <prog>.pcv 就 是 PureCoverage 数据文件。显示的 -percent=<nn> 指定了最低的覆盖率百分比;覆盖率低于这个数字的文件将会被报告成“低的”。默认的值是 80%。

范例::pc_below -percent=75 myprog.pcv

低覆盖率邮件报告:

Pc 邮件脚本产生了一个低覆盖率的邮件报告。该报告是对低覆盖率报告的一个扩展。它访问下面的脚本,并有着很低的覆盖率报告输出,检查作为低覆盖率数据列出的每一个文件的配置源代码控制数据,并决定谁最近使用了“rlog”系统命令来编辑文件。负责任的开发员会向他们发送一封电子邮件,通知他们文件上的覆盖率太低。RCS 当前支持 pc 邮件脚本,并需要与其他的源管理系统一起做一些编辑工作。

图 3 显示了一个范例,即一份报告被发送给电子邮件地址为xyz@us.ibm.com的开发员,他编辑的文件的覆盖率低于 75%。

% pc_email -percent=75 test.prog.pcv
Date: Wed, 13 Jan 2008 07:45:34 -0800
From: abcd@in.ibm.com (abcd QE)
To: xyz@us.ibm.com
Subject: Coverage too low
The following files have coverage which is too low:

20% /usr/p/src/mod1/foo2.c
66% /usr/p/src/mod2/baz.c
20% /usr/p/src/mod2/subdir/foo3.c

图 3:pc 电子邮件发送的低覆盖率邮件报告

运行 pc_电子邮件的语法结构是:

% pc_email [-percent=<nn>][<prog>.pcv...]

文件 <prog>.pcv 就是 PureCoverage 数据文件。选项 -percent=<nn> 指定了最低的覆盖率百分比;覆盖率在这个数字以下的会被报告为“低”。默认的数值是 80%。

邮件只会发送给那些使用代码行低于阀值的文件。如果没有文件低于要求达到的百分比,那么就不会发送电子邮件。

例如:pc_email -percent=75 test1.pcv test2.pcv test3.pcv

注释源报告:

对于和 g 选项相关的代码,PureCoverage 默认条件下同时收集了代码行层次和函数层次的信息(如果您在 purecov 命令行上使用了 -- purecov-granularity=function 选项,从而禁止收集代码行层次的覆盖率数据时,生成一个注释源报告是不可能的)。PureCoverage 默认条件下产生了代码行层次上的注释源报告。您可以指定选项 -type=block ,以查看基本的块覆盖率。图 5 显示了块层次的覆盖率的例子。不是每一个代码行都有一个命中,而是每一个基本块都有一个命中。所谓的基本块,就是不包含分支的代码的片段;它也许会也许不会响应一行源代码。一个例子就是:

1 a++;

2 b++;

3 c = a+b;

4 if (a == b) { c = 0;

5 d = 0;

6 }

7 e = 0;

1,2,3 行是声明行,第四行上是比较,所有这些组成了以传统跳跃执行结尾的基本块。行 4 和行 5 上的赋值组成了第二个基本块。行 7 开始了第三个基本块,因为赋值 e = 0;而且它并不是附属于第 4 行和第 5 行的,因为行 4 上的 if 声明也许会导致这些赋值被忽略。

报告会注释所有至少与在文件说明中给出的 <basenames> 的一项匹配的文件。如果您不去指定文件,那么报告会注释在指定的 .pcv 文件中提到过的所有文件。

在 PureCoverage 数据容器中也可以看到注释源类表。

pc_注释脚本会生成一个注释的源报告。当您使用g 调试选项汇编您的代码时,汇编器会在结果的对象文件中包含调试信息,该目标文件关联了项目指导的代码行行号。在这种情况下,PureCoverage 使用这些信息去显示执行每一行代码次数的注释源列表。数值 0 意味着该可执行行并没有命中。诸如评论之类的非执行行不会被注释,并不会对代码行覆盖率百分比的计算产生影响。在图 4 和图 5 中给出了注释源报告的一个范例。

执行 pc_注释的语法结构是:

% pc_annotate [-force-merge] [-apply-adjustments=no] 
[-file=<basename>...] [-type=<type>] [<prog>.pcv...]
% pc_annotate [-force-merge] [-apply-adjustments=no] 
[-file=<basename>...] [-type=<type>] [<prog>.pcv...]
% pc_annotate hello.pcv
======/people/nsrivast/hello.pcv(10% unused lines)=======

     |  main()
   1 |  {
   1 |   print_sum(); print_hello(); print_hello(); print_goodbye();
   1 |  }
     |
     |  print_sum()
   1 |  {
     |   int a,b,c,d,e ;
   1 |   a=10;
   1 |   b=20;
   1 |   a++;
   1 |   b++;
   1 |   c = a+b;
   1 |          if (a == b) { c = 0;
   0 |          d = 0;
   0 |          printf("value of c and d is %d %d", c, d);
     |           }
   1 |   e = 0;
   1 |  }
     |    print_hello()
   2 |  {
   2 |  printf ("hello!\n");
   2 |  }
     |
     |  print_goodbye()
   1 |  {
   1 |   printf ("bye bye!\n");
   1 |  }

图 4:带有代码行间隔尺寸的 pc_注释(注释源报告)

% pc_annotate -type=block hello.pcv
======/people/nsrivast/hello.pcv (12% unused blocks) ========
   |  main()
   1 |  {
   1 |   print_sum(); print_hello(); print_hello(); print_goodbye();
   1 +
   1 +
   1 +
   1 |  }
     |
     |  print_sum()
   1 |  {
     |   int a,b,c,d,e ;
   1 |   a=10;
   1 |   b=20;
   1 |   a++;
   1 |   b++;
   1 |   c = a+b;
   1 |          if (a == b) { c = 0;
   0 +
   0 |          d = 0;
   0 |          printf("value of c and d is %d %d", c, d);
     |           }
   1 |   e = 0;
   1 |  }
     |    print_hello()
   2 |  {
   2 |  printf ("hello!\n");
   2 |  }
     |
     |  print_goodbye()
   1 |  {
   1 |   printf ("bye bye!\n");
   1 |  }

图 5:带有 -type=block 的 pc_注释(注释源报告)

差异报告

差异报告比较两种类型的覆盖率数据,并报告覆盖率数据是怎样由于源代码或者测试中的更改而发生变化的。这对于追踪您的进程朝向覆盖率数据目标的情况,以及发现覆盖率的破坏非常有用。差异报告通过已存在的测试,或者要求书写新的测试,来决定是否给出一系列的代码变更集合。PureCoverage 提供三种类型的差异报告,它们如下所述。

差异报告:

pc_差异脚本生成一个差异报告。在软件开发的起始阶段,或者产品补丁的发布阶段,测试员会遇到程序或者测试集中的频繁改变,所以,人们对知道与收集的老数据相比,覆盖率的降低感兴趣,从而也对收集的新数据中添加或者删除的文件感兴趣。本篇文章对于分析覆盖率上的改变也十分有用,特别是对在收集老数据和收集新数据期间,对一些程序或者测试集上的更改更加有效。语法结构是:

% pc_diff [-apply-adjustments=no] old.pcv new.pcv
% pc_diff old.pcv new.pcv
Files which got worse:
Files which improved:
/usr/p/QE/atests/hash/ hash.c 61% changed to 92%
/usr/p/QE/atests/tests/ testHash.c 52% changed to 60%
Files which are new to new.pcv.
/usr/p/QE/atests/work/graphics/ view's 100%
/usr/p/QE/atests/work/graphics/ menu's 100%
/usr/p/QE/atests/work/graphics/ dialog.c 100% 
Files from old.pcv which no longer exist:
/usr/p/QE/atests/work/database/ utils.c 56%
/usr/p/QE/attests/work/subdir/ abc.c 100%
/usr/p/QE/atests/work/subdir/ test.c 60%
/usr/p/QE/atests/work/subdir/ name.c 100%

图 6:pc_diff (差异报告)

构建差异总结报告:

pc_build_diff 脚本生成了一个构建差异总结报告。它的目的与差异报告的目的相类似 。两种报告都会将覆盖率数据与前面的版本进行比较。构建差异总结报告具有一个额外的特性:它可以在目录中忽略一个日期或者时间标签,这样,就可以方便的比较来自两个不同日期的数据。报告的数据的差异是如此的大。构建差异不会按顺序列出所有的文件,而是为那些覆盖率提高的或者覆盖率恶化的部分,产生单独列表的文件。当您想要查看发生什么更改时,这种方式会更加方便,但是,如果您想要查找一个特定的源文件,或者它的已更改覆盖率数据时,使用差异报告才会更加方便。

语法结果是:

% pc_build_diff [-apply-adjustments=no] [-prefix=XXXX...]\ old.pcv new.pcv

脚本输出每一个 .pcv 文件,采取不同的结果数据,并显示处这些更改的总结。差异会以代码行的形式计算差异,这样只在 g 选项用于汇编时脚本才会起作用。所有的前缀都从目录名的左边获得,这样就可以比较来自构建区域的数据,甚至构建的根目录每天都会变化时也是这样。您可以指定特定的多种前缀格式,但是对于每一个目录名只能指定一种前缀。前缀以左对右的顺序排列。

注意:T前缀是一个 Perl 规范的表达式,以一个左边的(^)结尾。

对于 pc_build_diff 的一个例子,假设您使用格式 /usr/home/builds/daily.<date> 在已命名目录中构建或者测试的话,而且您使用的一个作为此次构建一部分的程序叫做 myprog ,它构建于工作版本的树形结构的 myprog 子目录中。进一步假设有一些该程序以及其他的程序使用的共享代码。这样,在您的文件系统中,您有 :

/usr/home/builds/daily.960408/myprog/main.c
/usr/home/builds/daily.960408/myprog/apply_patch.c
/usr/home/builds/daily.960408/myprog/myprog.pure.pcv
/usr/home/builds/daily.960408/shared/strings.c

和其他的源文件一样。您 还可以为工作版本的日期拥有相应的树状结构。为了比较4月 8 号和 4 月 9 号工作版本之间的覆盖率,来到 /usr/home/builds directsory,并运行:

% pc_build_diff -prefix=".*daily......./" \
daily.08090{8,9}/myprog/myprog.pure.pcv
This generates the following report:
*** Reduced coverage *** Unused Change | Used% Change
shared/ strings.c 61 +10 | 75% -3
*** Improved coverage *** Unused Change | Used% Change
myprog/ main.c 255 -3 | 70% 0
apply_patch.c 103 -1 | 75% 0
*** New files *** Unused Used%
*** No longer tested ***

图 7:pc_build_diff (构建不同的总结报告)

在命令中,这里写的是 csh {} 语法结构,前缀 .*daily......./ 来自于文件名的 /usr/home/builds/daily.<date>/ 部分(这个 Perl 表达式中的系列点,匹配诸如 .080908 之类的日期规约的七个特征)。然后指定两个 .pcv 文件。未使用的和改变的列用行进行测量。所以在 4 月 9 号的工作版本中,会测试字符串 C 的一些行。该工作会减少 3% 的已使用行。在主 .c 中,使用了三个额外的行(减少的三个未使用行),但是这个比例太小,以至于不能影响使用数字的百分比。

注释差异报告:

脚本 pc_covdiff 帮助回答了问题“我是不是测试了所有改变的部分?” 脚本会生成一个自动差异报告,一个包含了覆盖率信息的自动差异报告。就像注释源报告一样,注释差异报告会一行行的显示覆盖率信息。这就允许您将注意力放在您刚刚更改的代码之上,而不必去考虑未更改部分的覆盖率。

语法结构是:

% yourdiff <name> ... | pc_covdiff [-context=<lines>] 
[-format={diff|side-by-side new-only}] [-lines=<Boolean>]
[-tabs=<stops>] [-width=<width>] [-force-merge]
[-apply-adjustments=no] -file=<name> <file>.pcv ...

yourdiff 的值取决于您所使用的代码管理工具。例如,如果您使用的是 RCS ,yourdiff 就是 rcsdiff。

为 -file 选项指定同一个文件。这个脚本访问 pc_annotate 报表脚本,这样您就可以使用 pc_annotate 能够识别的任意一种形式的文件名了。列出 包含文件新版本的覆盖率数据的 .pcv 文件。如果您在这里指定了 -force-merge 选项,那么脚本将会将其传递给 pc_annotate。

您一次只能在一个文件中使用这个脚本。您不能从 PureCoverage Viewer 中去运行它。其他的选项控制了输出的格式。有两种输出的形式:diff 和 sdiff。在 sdiff 形式中,源的老版本和旧版本都各在一边显示出来,同时显示的还有两边之间的一列,它能指示是否添加、删除或者更改了行。在 style 形式中,老版本和新版本会顺序列出来,同时显示的还有指示发生什么情况的代码行。默认的形式是 sdiff。

选项 -format 允许您去指定形式:

-format=diff diff style
-format=side-by-side sdiff style
-format=new-only sdiff style, but without the "old" column

在 diff 和 sdiff 形式中,选项会脱离掉。使用选项 -tabs,如果您的文本编辑器在正常条件下,将 tabs 扩展为除了八个字符之外的值。

在两中形式下,您都可以在输出中包含额外的内容行 。默认选择是 2,但是如果您想要产生其他阅读 diff 的工具可以理解的输出的话,就将这个值改为 0.

在 sdiff 样式中,使用 -lines 选项(默认条件下是 TRUE)以指定,输出中是否应该包括行号码。

在 sdiff 样式中,您可以使用选项 -width 来指定源的每一列的宽度 。正常条件下,宽度值会随着输入的内容而自动改变大小。如果您指定一个明确的值的话,如果它们太宽的话,那么它就可以缩短。注意宽度是为源的每一列准备的,而不是总体宽度,后者包括了其他的选项,例如覆盖率数目,分开的列以及行号码,这取决于您所使用的选项。

图 8 显示了 pc_covdiff 脚本的使用。

# % rcsdiff foobie.c | pc_covdiff -file=foobie.c -width=29 -lines=no foobie.pcv
# ===================================================================
# RCS file: foobie.c,v
# retrieving revision 1.3
# diff -r1.3 foobie.c
#   Change             Old Version                     New Version          Usage
# =========== =============================   ============================= =====
#                        unsigned long                   unsigned long
#             {                               {                                 2
#       15a16                               >     int             result =      2
#                 unsigned long   i;              unsigned long   i;
#
#                 if (argc > 1) {                 if (argc > 1) {               2
#       19c20         for (i=0; i < num_ele |         for (i=0; (i < num_el     5
#                         if (MY_STR_EQ(tab               if (MY_STR_EQ(tab     3
# 21,23c22,25                 printf("runni |                 printf("Proce     1
#                             return((*tabl |                 printf("walki     1
#                             printf("back  |                 result = (*ta     1
#                                           >                 printf("back      1
#                         }                               }                     3
#                     }                               }
#                 }                               }
#
#       28c30     return(-1);               |     return(result);               2
#             }                               }                                 2
#
# ........... .............................   .............................  ....
#                 int i;                          int i;                        0
#
#       48d49         printf("barsoom: %s\n <
#                     printf("bim bam: %s\n           printf("bim bam: %s\n     0
#       49a51                               >         printf("bang, bang! %     0
#                 }                               }                             0
#                 return(1);                      return(1);                    0
# ........... .............................   .............................  ....
#
#             DispatchTable my_cmds[] = {     DispatchTable my_cmds[] = {
#    54a57,58                               >     { "foo", foo },
#                                           >     { "joe", foo },
#                 { "bar", bar }                  { "bar", bar }
#             };                              };
#####

图 8:pc_covdiff (注释差异报告)

测试覆盖率并编辑报告

测试覆盖率报告会识别需要更改为包含的一系列源文件的测试。直接让报告生成脚本执行测试也是可能的。

选择的测试报告

脚本 pc_select 会生成一个选择的测试报告,该报告能够处理选择一个合适的测试子集来运行,以测试对代码所做的有限更改的难题,在每一个更改之后,运行整个的测试集的话就会太过耗时,所以,典型的做法是,用户在不运行任意测试集的前提下,更新主源代码。那么,作为一个构建的过程,运行并报告整个的测试集。

该操作存在一些问题,例如:

  • 如果更新引入一些问题的话,剩余的开发组在等待一次修复时,也许会被“堵塞”住。
  • 如果有些开发员做了一些更改后,哪一个代码导致问题出现会很模糊。
  • 如果已经有一些开发员引入一些漏洞的话,一系列的问题可能会引起其他的问题,这样在代码的初始更新和被引入的问题最终被发现这段时间内,就会导致一些延迟。
  • 当最终发现问题之后,开发员也许陷入另外一个更改之中,让情况变得麻烦,并且很难停止手中的事情,去解决出现的问题。

脚本 pc_select 会开发一种方法,以运行测试集的子集,需要用该测试集去测试刚刚作出的更改。这可以大大降低需要的测试时间,让在更新代码之前进行合适的测试变得更加容易。结果就是日常构建中的降级风险被大大降低了。

尽管一些测试工具支持任意测试子集的选择,但是它们仍然不能决定,测试的哪一个子集是测试给出更改的合适选择。脚本 pc_select 能够解决这个问题,它假设 :

  • 您的测试工具支持任意测试子集的选择。
  • 有一系列可以使用的 .pcv 文件,每一个测试用例都有一个,这也需要运行;而且您有一种方法能够从 .pcv 文件的名字中,决定哪一个测试用例与其相匹配。最常见的做法是,在单独的子目录中运行每一个测试。并在它自己的本地 test.pcv 文件中收集数据。
  • 您可以识别编辑哪一个源文件。有一些方法可以决定每一个源文件和 diff 输出的全集,识别作出的更改,因为每一个测试的覆盖率数据都被收集了。

当运行 pc_select 时,它会搜索所有的覆盖率文件,并识别执行每一个更改函数的覆盖率文件。覆盖率文件的结果列表是输出。它们可以被转化为您想要运行的任何表格,只要与测试集的测试表格相关即可 。

% <changed files> | pc_select [-diff=<rule>] [-canonicalize=<rule>] <file>.pcv ...

列表<changed files> 通过 stdin 指向 pc_select ,应该包含文件名,每一个行都有一个,识别每一个更改的文件,因为收集了覆盖率数据。例如,如果您为最近三天作出改变的话,您可以使用一个搜索命令,来产生正确的列表,然后将该列表指向 pc_select 命令:

% find * -type f -mtime -3 -print | pc_select

选项 <rule> 用于精确的指定,怎样为每一个文件获得 diff 输出。对于 IBM Rational ClearCase®,它可能会是“\'cleartool diff -diff -- predecessor \$file\' ”或者一个相似的角色。

-canonicalize <rule> 是一个通用的 Perl 表达式,反过来对每一个文件应用它,以决定使用什么名字来在 .pcv 文件中放置您的覆盖率数据。在评价表达式时,变量 $file 包含了可以在 stdin,中找到的名字,出于方便考虑,变量 $_ 也被赋予相同的值。

-canonicalize <rule> 的默认值是:

-canonicalize='chop (local ($here) ='pwd'); "$here/$file"'

这可以将一个相对路径转化成绝对路径,使用 pwd 来计算全路径。对于这里显示的例子,如果文件名就是文件的文件的基本名,那么您就可以使用 :

-canonicalize='"/usr/builds/951211/src/$file"'

自动选择测试报告和运行:

脚本 pc_find_tests是对脚本 pc_select 的扩展,它能够完全自动化搜索和运行您的代码更改的测试集。您可以编辑 pc_find_tests 以让它和您自己的项目协同工作。它涉及到您的源控制系统,以找出哪一个源文件被更改了,然后涉及到带有合适选项的 pc_select ,以找出需要运行哪一个测试。然后它会为您列出测试:这就是自动选择的测试报告。或者,如果您对其进行编辑,所以它可以和您的自动测试系统进行交流,它可以执行测试并报告它们的执行结果 。如果源控制系统是 ClearCase的话,pc_find_tests 可以作为 ClearCase 激发器安装,这样每次检入一个代码更改的时候,它都能自动运行一系列的合适测试。

语法结构(用户没有进行任何的更改)是:

pc_find_tests[-testroot=<directory>][-vob=<vob>][-verbose]

输出的格式将会随着您对脚本的编辑情况而变化。图 9 中给出了一个例子。

该脚本就是 7.0.0.0-01 版本中的 PurifyPlus 。如果您在 PureCoverage 安装文件中没有一个复制版本的话,您可以从下面参考资源 段落中列出的网站中下载 pc_find_tests 。只要将其拷贝到 purecov_home/scripts 中即可。

% pc_find_tests

Changed functions:
	/vobs/cov_demo/src/math_func.c     	calc_distance
	/vobs/coV_demo/src/print_report.c	report_distance
To test these changes, run these tests:
	geometry1
	geometry2
	report_generator
Do you want to run these tests now? [yes] y
The tests to run are:
	geometry1
	geometry2
	report_generator
Running test geometry1
	PASSED
Running test geometry2
	PASSED
Running test report_generator
	PASSED

TEST SUMMARY:
	3 test executed
	0 tests failed
	3 tests passed
	pass rate: 100%

图 9:自动选择的测试报告以及执行(pc_find_tests)。

实用性报告

实用性报告组织覆盖率数据,以便和诸如 spreadsheets 和 Web browsers 之类的工具共享这些数据。

pc_ssheet (或者 spreadsheet 报告):

如果您想从输出数据覆盖率中生成一个项分开文本报告的话,那么 spreadsheet 报告就是答案。pc_ssheet 脚本生成这个报告,它可以为进一步分析而读成一个 spreadsheet 项目,例如,每一个函数。报告包括了目录名以及函数名。

如图 10 所示,每一行的最右边的号码,显示了未包含行的百分比,以及函数的全部访问;例如,在第一行中未包含行的百分比是 100 ,因此对该函数的全部访问是 0。

语法结构是:% pc_ssheet [<prog>.pcv...]

/usr/p/QE/work/message/ utils.c unused_function 100 0
/usr/p/QE/work/message/ utils.c heavily_used_function 0 1000
/usr/p/QE/work/message/ utils.c somewhat_used_function 0 25
/usr/p/QE/work/message/ shifty.c empty_line 0 100
/usr/p/QE/work/message/ shifty.c empty_line2 0 200
/usr/p/QE/work/database/ utils.c unused_function 100 0
/usr/p/QE/work/database/ utils.c heavily_used_function 0 10000
/usr/p/QE/work/database/ utils.c somewhat_used_function 0 25

图 10:pc_ssheet (preadsheet)报告范例

需要注意的一件重要的事情,便是当全部访问的数值达到 100 时,从第二个倒最后一个函数,计数器都会溢出并且停止增长。

purecovweb.pl (PureCoverage HTML script):

您还可以将一个包含了输出覆盖率数据的文件,转化为可以在 Web 浏览器中浏览的形式。这是通过在输出的覆盖率结果上运行 Perl 工具来完成的,结果导致了Web 格式呈现日期的文件的新结构。这就允许您在私人之间共享数据,而不需要安装一个 PurifyPlus Client。预期的是哪些使用这些特性的部分,将会是私人的,例如项目领导、程序管理员,或者其他对覆盖率数据感兴趣的人,但是这些人并不是积极使用 PurifyPlus 的。Web 格式同样能够在报告中参考信息,或者项目状态报告的其他方法。

该语法结构能够激发工具,purecovweb.pl 是:

perl purecovweb.pl [<options>] PureCoverage-txt-File

该条命令能够阅读 Rational PureCoverage 文本文件,以产生一系列的 HTML 文件。起始的 HTML文件就是 UNIX 上的 index.html 。 purecovweb.pl 使用的图片,被复制到同一位置。这种项目预计名为 purecovweb_files 目录中的 JPEG 文件,位于和  purecovweb.pl 脚本相同的目录中。

注意:该脚本可以在 PurifyPlus 的 7.0.0.0-010 和后续的版本中得到。

使用 PureCoverage 输出格式数据书写您自己的脚本

您已经学习了,报表脚本是怎样让处理 PureCoverage 数据,以查看各种格式的,以及您是怎样直接使用默认的脚本或者编辑它们的。但是这并不是您能对 PureCoverage 所做的一切。如果您感到需要书写您自己的脚本,以编辑报告形式的话,那么您可以使用 PureCoverage 输出格式来写出您自己的脚本,以生成通用的报告。

PureCoverage 输出格式是 ASCII 形式的,并用于将覆盖率数据转化为其他的项目。输出格式包含了关于目录、文件、函数、行以及块的总结信息。

按照以下步骤,创建一个通用报告:

  • 将合适的 PureCoverage 数据文件转化为输出格式。为了获得输出数据,使用命令 purecov –export。
  • 读取输出数据并将其转化为需要的形式。

一个简单的通用报表脚本

让我们看一下怎样书写一个简单的报表脚本,该脚本在一个项目中为一个特定的函数记下行覆盖率百分比。脚本语法结构为:

myfunc <program> <function>

这里 myfunc 是一个脚本,<program> 是要搜索程序的名字,而 <function> 是要显示函数的名字。脚本自动添加 .pcv 扩展名为程序的名字,而且忽略无效参数的可能性。在图 11 中显示出了通用的报表脚本 myfunc ,而且您可以使用它作为书写您自己脚本的模板。

#!/usr/local/bin/perl
# Usage: myfunc program function
# Reports coverage for "function" which is used by "program".
# Example: myfunc myprog main
open(EXPORT, "purecov -export $ARGV[0].pcv |");
while (<EXPORT>) {
if (/^di/) { ($key, $curdir) = split(/\t/); }
if (/^fi/) { ($key, $curfile) = split(/\t/); }
if (/^fu/) {
($key, $curfunc, $ign, $ign, $unused, $lines) =
split(/\t/);
if ($curfunc eq $ARGV[1]) {
$count = $lines - $unused;
$percent = ($count * 100) / $lines;
push(@matches,
sprintf("%3d%% %s%s:%s\n", $percent, $curdir,
$curfile, $curfunc));
}
}
}
close(<EXPORT>);
print sort @matches;

图 11:这里显示的通用报表脚本,可以作为书写您自己脚本的模板。

基本脚本结构使用 purecov 来生成输出数据,而且提取出函数信息并在数组 @matches 中记录下来。如果在程序中函数的名字不止一次被使用,那么它会使用分类来组织数据。

命令行 purecov 使用 –export 选项 ,和 $ARGV [0],程序名一起,从您在运行脚本时指定的程序中输出数据。

白色的环有三个主要的模板匹配部分。该报告从输出数据中处理三种不同类型的行:

  • 目录名包含了文件
  • 文件名包含了函数
  • 函数名加上函数的覆盖率信息

关键字的前面(^)让模板只让模板与行的开始处相匹配。对于文件和目录行,您只需要记录下名字。对于函数,您也想从 $unused 和 $lines 中记录下行覆盖率,计算覆盖率百分比,并写出函数信息。

在您运行脚本时,您为您所指定的函数得到覆盖率信息,如图 12 所示。

% chmod +x myfunc 
% myfunc myprog myfunc 
70% /home/pat/dir1/file1.c:myfunc

图 12: 您为您所指定的函数得到覆盖率信息。

使用 PureCoverage 脚本

PureCoverage 自动化的报表脚本可以直接从命令行中使用,或者您也可以在 PureCoverage 浏览器中选择报表脚本,PureCoverage 浏览器可以根据您特定的需求,来帮助您去编辑 PureCoverage 输出。命令行和浏览器中的脚本使用语法一般相同,但是并不是所有的脚本都可以从浏览器中运行(例如,pc_covdiff)。根据以上讨论,您就可以直接使用默认的脚本,编辑它们,或者将它们作为您自己脚本的基底使用。可以在 purecovhome>/scripts 目录中得到这些脚本。

我们已经为命令行的脚本使用提供了语法。如果您想从 PureCoverage 浏览器中使用脚本以分析的话,那么就按以下步骤来做:

  1. 在 PureCoverage 浏览器中点击 File > Run script。该操作能够打开列出所有可用脚本的更多浏览器 ,如图 13 所示。

Screen image

Screen image

图13: The PureCoverage viewer

  1. 选择一个如图 14 左边所示的脚本,并在其他不同支持的选项中选择。指定文件作为每一个需求并点击 OK 以生成报告。

Screen image

Screen image

图 14 :浏览器允许您去选择一个脚本,还提供不同的支持选项。

总结

当您评价代码覆盖率时,原始数据的数量会非常的巨大。它尝试着查看总结“全部覆盖率”数值,并忽略剩余的部分。或者您可以花费数小时时间研究细节,并试着弄清您需要为您的测试工具添加什么类型的测试。覆盖率脚本可以组织原始数据,并以您所需要的能够作出关于测试有效信息的形式提取信息。

IBM Rational PureCoverage 提供了一系列的生成代码覆盖率的脚本。同样还有帮助基于源代码更改基础之上自动化测试执行的脚本。实用性脚本让其他程序能够共享PureCoverage 数据,例如 spreadsheets。如果这些脚本中没有一个是您所需要的话,那么您可以复制并编辑这些报表脚本,以创建您自己的通用报告,该报告回答了您需要回答的问题。不要在总结的顶部,限制您对覆盖率数据的使用为单个号码。试着将报表脚本自动化,并弄清覆盖率数据是怎样帮助您管理您的项目的。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=360197
ArticleTitle=PureCoverage 报表脚本:最大限度利用您的覆盖率数据
publish-date=12182008