不可达语句自动检测方法研究

          在白盒测试中,测试人员重要任务之一就是查找不可达语句。很多软件相关人员尤其是开发人员都存在一种错误的观念,他们认为不可达语句对程序的质量影响不大,不可达语句仅仅增加了代码的存储容量,降低了代码的可读性而已。可他们没有想到这一点:在设计上,是不会设计出不可达语句的,所以正常的编码中是不应该存在不可达语句的,尤其是绝对不能出现路径不可达语句与逻辑不可达语句。如果存在这两类不可达语句,很可能的原因是出现了编码错误。对于航空、航天、军工等行业的软件,出现这样的错误往往会带来灾难性的后果。因此,对于白盒测试人员来说,尽量全面的找出代码中存在的不可达语句是一项非常重要的工作。然而,面对动辄上万,十万乃至百万行的代码,测试人员往往只能是尽力而为了。因此,如果找出一种方法能够自动的查找出不可达语句,必将会大幅度降低测试人员的工作量,促进代码质量的提高。下面我们就对不同种类的不可达语句的查找方法进行阐述。

         不可达语句的分类方式有多种,在本文中按照形成原因将不可达语句分为三大类:路径不可达、逻辑不可达和运行不可达。

        路径不可达是指在控制流图中不被任何路径经过语句。在该类中又分为两个小类:“孤岛”语句和“被跳过的语句”。“孤岛”可能是函数、类或者文件。“孤岛”同海洋中的孤岛是存在差异的,海洋中的孤岛尽管同大陆隔离,但是借助船只、飞机等交通工具还是可以达到的。而本文中的“孤岛”是同其它代码没有任何关联的绝对的孤岛。通常有人认为这是不存在的,但是对于具备相当规模的软件来说,尤其是对于具有研发性质的软件来说,孤岛并不罕见。对于“孤岛”语句,在对被测软件进行充分词法分析和语法分析的基础上,通过变量分析、函数调用分析、对象调用分析等静态分析方法可以查找出软件中所有的“孤岛”。   

被跳过的语句是指在跳转语句之后以及跳转目标点之间的语句。如下面代码中所示:

1                If(a>b)

2                {

3                          goto    Lab el1;

4                          a=a+1;////被跳过语句

5        }
6 Label1:

……   

第四行代码就属于被跳过的语句。对于这类语句,在词法分析、语法分析的过程中,通过检测跳转关键词后面的语句是否与跳转关键词属于同一语句块就可以判断其是否属于被跳过的语句。

逻辑不可达语句是指尽管存在路径覆盖,由于自身的前置条件永远为假或者永远不被检测的原因而形成的不可达语句。前置条件通常是指分支语句中的入口条件。根据不可达的成因。该类又可分为永假条件不可达和愈强条件不可达。

永假条件顾名思义是指条件的取值永远为假。对于此类问题,需要在词法分析、语法分析的基础上进行数据流分析、变量分析及分支条件的表达式分析。首先判断表达式是否可以直接计算,如果可以,可计算出表达式的值,如果值为0,则分支块中的语句为不可达语句,如果值不为0,在if..else语句中,else块中的语句均为不可达语句,在if…else if 结构中,当前if或者else  if后面的else  if 及else语句块中的语句都为不可达语句。如下面代码中所示:

1      If((5+3<4)&&(a>(a+1)))

2       {

3                b=5;  

4    }

表达式(5+3<4)&&(a>(a+1))可以计算,计算的值为0,所以第三行为不可达语句。如果表达式不可计算,要根据真值表判断表达式是否为矛盾式,如果为矛盾式,则该分支语句块中的语句均为不可达语句。如为重言式,在if..else语句中,else块中的语句均为不可达语句,在if…else if 结构中,当前if或者else  if后面的else  if 及else语句块中的语句都为不可达语句。如下代码所示:

1       If((a>b)&&(a<(b-1))

2       {

3                c=5;

4       }

由于(a>b)&&(a<(b-1)为矛盾式,所以第三行为不可达语句。如果不能直接判断是否为矛盾式,如果表达式中没有应用到同函数中的局部变量,不做后续处理。如果用到了变量,需要结合数据流分析的结果获取原始变量条件表达式,对原始变量条件表达式重新进行表达式求值及矛盾式的判断,如下面代码所示:

1          Int a=10;

2          Int b;

3       If(a==5)

4       {

5                b=3; …

6       }

表达式a==5不能确定是否为矛盾式,也不能直接进行表达式求值,但在表达式使用了变量a,将路径中的a=10;整合到a==5中,获得原始变量条件表达式10==5,该表达式可直接计算且表达式的值为0,故第5行为不可达语句。有两种情况需特殊处理,首先是对于if…else  if 语句,不但要检测单个入口条件表达式,还要检测当前入口条件表达式同语句结构中前置关联入口条件的组合表达式。另外就是swtich语句,需要将switch变量同case值组合成条件表达式进行检查,如果switch是枚举类型,需要检查case的值是否为枚举元素。

         愈强条件不可达主要是针对if…elseif…else语句结构的。如果某个else if的入口条件是前面关联入口条件或者某几个关联入口条件的子集,那么该条件就是前面入口条件的愈强条件,由于执行顺序的原因,该入口条件中语句是不可能被执行的。如下面代码所示:

1        Int a=10;

2        Int b;

3       If(a>5)

4       {

5                b=3; …

6       }

7   else if(a>7)

8       {

9                b=6;

10     }

11  else

12   {       

13              …

14     }

第七行的入口条件表达式a>7是第三行入口条件表达式a>5的子集,所以第九行为不可达语句。

运行不可达指的是软件在实际运行过程中,输入数据有明确的取值范围,在词法分析、语法分析的基础上,需要进行变量分析及表达式分析,在取值范围内,结合数据流分析笔,在必要的情况下,还要应用约束求解技术,对分支语句的入口条件表达式进行分析,从而找到不可达语句。处理过程与逻辑不可达类似。

1//计算成年男人的标准体重

2       float get_weight_of_men(float fHeight)

3       {

4                float  fRet;

5                If(fHeght<40)

6       {

7               fRet=0;
8       }

9                else if( fHeght>350)

10              {

11                       fRet=0;

12              }

13              else

14              {

15                       fRet=(fHeight-80)*70/100;

16              }

                   return     fRet;

17     }       

在实际应用中,fHeight的取值范围是(50,300),应用约束求解技术,可得到Heght<40无解,fHeght>350也无解,因此第七行和第11行为不可达语句。

        对于这三种类型的不可达语句,通常是先检查路径不可达语句,既而检查逻辑不可达语句,如果条件具备,最后检查应用不可达语句。该方法已经系统地应用到“测试之家”研发的软件“不可达语句检测工具”当中。当然,并不是说应用了“不可达语句检测工具”就能够检测出全部的不可达语句。从技术层面来说,由于约束求解技术的不完善导致存在部分不可达语句不能检测出来,这主要体现在“运行不可达”语句的检测方面,因此,对于“运行不可达语句”的检测,在应用工具的基础上,目前仍然需要测试人员对特定语句进行人工检查。


                                                                                                                                                                                                 "测试之家"官方网址:http://www.tlemp.com

                                                                                                                                                                                                                              QQ: 871257051

                                                                                                                                                                                                                            mail: [email protected]


猜你喜欢

转载自blog.csdn.net/plstudio1/article/details/77209049