这里没有软件测试的泛泛理论,只有博主的最佳实践。 博主的研究方向为静态分析和性能测试,致力于各种测试工具的引入、评估和开发。 本博的测试文章均为作者原创,转载请务必注明出处。

我看“覆盖率测试”

上一篇 / 下一篇  2008-01-17 14:40:51

白盒测试的静态部分上篇(我看“静态测试”)已经讲过了,本篇我想说的是白盒测试中的动态部分。本文涉及到的内容很多,所以本文不求面面俱到,只要说明思路即可。

白盒测试的动态测试要根据代码的控制结构设计测试用例。为了在有限的时间和有限的资源内达到最佳的测试效果,传统的测试理论采用了几种优化的设计方法,即逻辑覆盖法和基本路径法。逻辑覆盖通过对程序逻辑结构的遍历实现程序的覆盖,最常用的一般是语句翻盖、分支覆盖等。

      在很多行业的测试标准中,通常会对测试要达到的覆盖率有一定的要求,例如要求语句覆盖率和分支覆盖率必须达到100%。一般情况下,要实施覆盖率测试,有三种完全不同的策略。

1黑盒测试(功能测试

      黑盒测试是面向功能的测试,测试用例的依据是软件的需求,测试的对象是运行起来的软件。通常情况下,一个有经验的测试工程师根据需求说明书编写的测试用例在执行完成后,覆盖率一般能达到70%左右,需要N工作日。要达到覆盖率的最终目标100%,还需要增加新的测试用例。有过覆盖率测试经验的朋友知道,剩下的30%可能需要N *3工作日,甚至更多。理由很简单,留给朋友意会吧。形象点说明,请看效果图。

2白盒测试

      和黑盒测试正相反,白盒测试的测试用例的依据就是软件代码。测试工程师需要依据代码的逻辑结构、基本路径的分析,得到测试用例。因为该方法直接面向代码,写出的测试用例非常有针对性,每执行一个用例,覆盖率指标都能有新的提高,最终达到终极目标。听起来很不错,其实还有一个很大的问题,就是测试工程师需要分析所有代码的逻辑结构、调用关系、数据流等,仅此一项,就需要花费巨额的时间。请看下面的效果图。

 

3白盒和黑盒结合的方法

      既然黑盒和白盒各有优劣,所以不如采用二者相结合的方法。先黑盒,把基本的功能都测试一轮,覆盖率达到70%;第二步,根据前面的结果,单独分析剩下30%的代码,使用白盒的方法增加测试用例,最终达到终极目标。经过很多客户的实践经验,这种混合的方法对于覆盖率测试是最有效的。

 

4覆盖率测试的局限

举一个简单的例子来说明代码覆盖率的局限。

 

      static void Recursion (int* depth)

97       /* if depth<0, recursion will lead to division by zero */

98       {  float advance;

99   

100          *depth = *depth + 1;

101          advance = 1.0/(float)(*depth - 6); /* potential division by zero */

102                                    ……………..

}

 

在做代码覆盖率测试时,只需要一个测试用例

*depth = 10;

就可以使以上的代码覆盖率达到100%。如果只是追求高覆盖率尽快达到要求的话,就很可能漏过*depth = 5会导致除数为0这样的致命的错误。

当然实际的代码可能会更复杂,不会那么简单。假如GlobalFlag是一个被多个任务使用的全局变量,*depth = 10这一个测试用例可能也会让代码覆盖达到100%,但这个100%能保证下面代码中的除数不为0吗?

 

      static void Recursion (int* depth)

97       /* if depth<0, recursion will lead to division by zero */

98       {  float advance;

99   

100          *depth = *depth + 1;

101          advance = 1.0/(float)(*depth - GlobalFlag); /* potential division by zero */

103                                    ……………..

}

 

我认为覆盖应该分为两种,一是传统意义上说的结构覆盖,即逻辑覆盖(语句覆盖、分支覆盖等)和以及基本路径覆盖,第二是数据输入覆盖

什么是数据输入覆盖呢?就是测试用例的输入占软件所能接受的全部输入的百分比。还用以上例子来说,

int *depth能接受的全部输入为65536个(-32768+32767

当前测试用例输入的个数为1*depth = 10

这样的结果是:

      语句覆盖率为100%

      但输入覆盖率仅仅为1/65536(接近于0

 

      其实这个问题也就是软件测试的完全性的讨论。软件测试原则之一就是不可能做完全的测试。由于工作量、时间、以及资金等等的限制,传统的覆盖率测试方法无法做到完全的测试,所以就有了测试用例的优化方法,比如只使用基本路径覆盖,循环当作一次判断选择等等,采用这些方法很容易漏掉一些致命的问题。

      结合其他方面,简单总结一下,就是

l        覆盖率测试可能发现不了一些与数据相关的错误

l        覆盖率测试不可能查出程序中因遗漏路径而出错

5覆盖率测试最佳实践

l        不要特意的去做覆盖率测试,也就是说,不要以覆盖率指标为最终目的。
接触过的一些客户,因为公司的覆盖率指标100%的要求,特意的去满足覆盖率测试指标,为了测试而测试,搞得大家都很累,最后还什么都没发现。测试的最终目的是为了发现错误,时刻牢记这一点。但刚才提到的客户却忘了,到最后唯一的信念就是覆盖率,希望尽快达到指标,完成任务。这种做法偏离了软件测试的目的,走上了错误的方向,当然达不到好的效果。

l        覆盖率测试作为功能测试完整性的衡量指标之一。
建议不要特意的去做覆盖率测试。可以考虑在做功能测试的同时,顺便查看覆盖率情况。把覆盖率数值作为功能测试完整性的一个衡量指标。

l        借助于专业的工具实施覆盖率测试
没有专门的测试工具,覆盖率几乎没有办法得到。目前覆盖率测试的工具有很多,每个工具都有自己擅长的地方,这里的关键是选择适合自己应用的工具。

 

 

以上是我自己的观点总结,不一定完全准确,仅供参考。有不同意见的可以交流。

 


TAG:

 

评分:0

我来说两句

Open Toolbar