代码插入

本章是代码覆盖率分析中示例的延续。

覆盖扫描器会在如下示例中插入仪器化代码。(包含的代码以粗蓝体显示。)

  • 顺序语句:语句在执行前进行仪器化。仪器化包括分配一个布尔变量以便检测代码是否被执行。

    示例:

    a=foo();
    a++;
    break;

    将被更改为

    a=foo();
    a++;
    { inst[0]=1; break; }
                

    inst[0] 在执行到 'break' 语句时设置为 1。

  • 条件语句和布尔表达式(全仪器化):对于布尔表达式,原则相同,只是在记录执行本身的同时,还记录状态(真或假)。

    示例:

    if ( a<b )
      return 1;

    将被更改为

    if ( (a<b) ? inst[0]=1 : inst[1]=1,0 )
      return 1;
                

    inst[0] 在布尔表达式 a 为真时设置为 1。

    inst[1] 在布尔表达式 a 为假时设置为 1。

  • 条件语句和布尔表达式(部分仪器化):在某些情况下,记录布尔表达式的值对于顺序语句的仪器化是不必要的。例如,if (b) return 0; else return 1; 语句被顺序覆盖率完全覆盖——毕竟,记录 `b` 是否为真并不提供额外信息。同样,对于语句 if (b) return 0;,只需要检查 `b` 是否为假。默认情况下,Coco 会抑制生成冗余仪器化,以最小化仪器化代码的大小并最大化执行速度。

    示例:

    if ( a<b )
      return 1;

    将被更改为

    if ( a<b )
      return 1;
    else inst[0]=1 ;
                

    inst[0] 在布尔表达式 a 为假时设置为 1。由于顺序覆盖率记录了指令 `return 1;`,因此不需要记录 `a` 是否为真。

需要插入以提供先前 foo() 函数示例的语句覆盖率所需的仪器化代码意味着函数代码被转换为以下代码

char inst[5];
void foo()
{
  bool found=false;
  for (int i=0; (i<100) && (!found); ++i)
  {
    if (i==50 ) { inst[0]=1;break;}
    if (i==20 ) { inst[1]=1;found=true;}
    if (i==30 ) { inst[2]=1;found=true;}
  inst[3]=1; }
  printf("foo\n");
inst[4]=1; }
    

如果我们为支持决策覆盖率插入必要的仪器化代码,结果代码将看起来如下

char inst[13];
void foo()
{
  bool found=false;
  for (int i=0; ((i<100 && !found)?inst[0]=1:inst[1]=1,0); ++i)
  {
    if ((i==50?inst[2]=1:inst[3]=1,0)) {
    inst[4]=1; break;}
    if ((i==20?inst[5]=1:inst[6]=1,0)) {inst[7]=1; found=true;}
    if ((i==30?inst[8]=1:inst[9]=1,0)) {inst[10]=1; found=true;}
  inst[11]=1; }
  printf("foo\n");
inst[12]=1; }
    

如果我们向这个示例中插入支持条件覆盖率所必需的检测代码,生成的代码将如下所示(除了一行换行以更好地适应页面布局)

char inst[15];
void foo()
{
  bool found=false;
  for (int i=0;((i<100)?inst[0]=1:inst[1]=1,0) &&
       ((!found)?inst[2]=1:inst[3]=1,0); ++i) {
    if ((i==50?inst[4]=1:inst[5]=1,0)) {inst[6]=1; break;}
    if ((i==20?inst[7]=1:inst[8]=1,0)) {inst[9]=1; found=true;}
    if ((i==30?inst[10]=1:inst[11]=1,0)) {inst[12]=1; found=true;}
  inst[13]=1; }
  printf("foo\n");
inst[14]=1; }
    

以下是插入条件覆盖率部分检测代码后的代码外观(同样,其中一行已换行)

char inst[12];
void foo()
{
  bool found=false;
  for (int i=0; ((i<100)?inst[0]=1:inst[1]=1,0) &&
       ((!found)?inst[2]=1:inst[3]=1,0); ++i) {
    if (i==50 ) {inst[4]=1; break;} else inst[5]=1;
    if (i==20 ) {inst[6]=1; found=true;} else inst[7]=1;
    if (i==30 ) {inst[8]=1; found=true;} else inst[9]=1;
  inst[10]=1; }
  printf("foo\n");
inst[11]=1; }
    

Coco v7.2.0©2024 Qt公司有限公司。
Qt以及相应的商标是Qt公司(芬兰)在全球的商标。所有其他商标均为其各自拥有者的财产。