海量测试用例如何优化:用状态矩阵解决有序操作的case爆炸问题(2)

发表于:2012-09-26来源:百度质量部作者:qabloger点击数: 标签:软件测试
说白了,上面状态图里的各种可能组合,都可以发生,用户可以沿着箭头所指的方向,不停的走下去。如果我们有某种组合没有测到,可能发生一些异常。

  说白了,上面状态图里的各种可能组合,都可以发生,用户可以沿着箭头所指的方向,不停的走下去。如果我们有某种组合没有测到,可能发生一些异常。

  为了避免异常的发生,我们要测试尽量多的组合。组合的覆盖率要达到怎样的程度?

  根据pairwise[3]的理论,90%以上的bug都是由两两成对的操作导致的。而在网站ajax页面测试中,可能这个数值会稍低一些。依据经验,我们发现大于两步操作的bug还是有一定数量,但是一定要大于三步操作才能发现的bug则很少。

  因此我们暂时将覆盖率“拍”为“覆盖所有的三步操作组合”。如果测试设计能够达到这个覆盖率,那应当是非常全面了。

  我们先制定这样一个覆盖率目标,事实上这个三步可以理解为N步,只是一个宏定义,再看怎么能简化。

  3. 怎样达到这个覆盖率?

  目标是“覆盖所有三步操作”,有了上面的状态图,通过遍历状态图,就可以做到了。画状态图,是不是有点麻烦?

  进一步,将状态图抽象一下,用状态矩阵来表示,遍历这个状态矩阵,就可以穷尽三步操作。

  那首先要完成状态矩阵这个体力活,根据上面的状态图,图中的页面用0-9来表示,从行号到列号,可以转换为1,不可以转换为0。

  我们可以得出如下的矩阵:

  接下来用程序遍历这个矩阵,找出所有2步及3步的操作,可以得到162个组合case:

  0 1

  0 2

  0 3

  0 4

  0 2 1

  0 2 3

  0 2 4

  0 2 6

  0 3 1

  0 3 2

  0 3 4

  0 3 7

  0 4 1

  0 4 2

  0 4 3

  0 4 7

  2 1

  2 3

  2 4

  2 6

  。。。。

  有了这些case,覆盖率一定很全了。

  4. 如何缩减这些case

  覆盖率目标达到了,但是有162个case,除了单个页面的功能验证,我们还要进行这么多的组合case测试,工作量太大。那么如何缩减这些case?

  观察这些case,如果我们挨个做,很多步骤是重复的。例如,上面有这样4个case:

  0 3 2

  3 2 4

  2 4 7

  4 7 4

  这4个case可以首尾相接,变成 0 3 2 4 7 4。把case中有重复的步骤合起来,4个case变成了一个case。

  这个思路不错!按照这个思路,我们可以将case合并起来,4合1,case数量大大缩减。

  当然,不会那么巧,所有的case都能4合1、3合1,我们还会有些疑问:

  1. 是不是所有的case都可以合并? 还是上面的例子只是个特例?

  2. 合并到什么程度?是否需要把10多个三步操作都合并起来,得到一个20多步的操作? 这个问题经过讨论,一般认为操作步骤在6~8步比较合理,组合的case不是很大,所能验证的内容也比较多,对于测试人员来讲是最“舒服”的。

  这个思路是不是可行,我们先合并一下试试看!

  5. 合并后的结果

  有了思路就开始做。

  先尝试一下把这162个小于3步的操作合并成一些6步的操作。我们采用这样的算法:

  1. 先算出所有6步操作,记为集合A; 将所有小于等于3步操作的集合记为B;集合C为最终结果集合,目前是空集;

  2. 算出每一个6步操作能够包含几个2-3步的case,并将包含最大值记为max;

  3. 如果max>1,则将能够取得max值的那个6步操作,加入集合C;把这个6步操作和其所包含的2-3步操作从各自的集合中删除;返回2继续;

  4. 如果max=1,则将集合B中剩余的元素全部加入C中,得到结果集合C,退出

  简言之,算法会从所有6步操作的集合中选出能够包含这162个case的最小集合,其中可能有部分case无法合并,无法合并的case直接进入结果集。这个算法可能不是最优的,但是已经尽可能找到了那个最小集。

  经过算法合并以后,得出了如下结果:

  用多步操作来合成3步操作,需要 35个case,这35个case覆盖了162个case中的151个:

  0 2 3 2 3 4

  0 3 7 2 4 1

  0 4 2 6 2 1

  4 7 5 8 4 3

  2 6 5 9 5 1

  5 2 6 3 7 1

  5 3 7 3 7 4

  5 4 3 2 6 1

  。。。。。。

  剩余11个case无法组合:

  0 1

  0 2 1

  0 3 1

  0 4 1

  8 2 3

  8 2 4

  8 3 1

  8 3 4

  8 4 1

  8 4 2

  9 5 2

  这些无法组合的case,是因为有的状态没有出路,走到这里就会终结了。

  于是,我们用35个6步的case,覆盖了原来162个case中的151个,剩余11个case,需要再单独验证一下。总case数为35+11=46个,在可以接受的范围内。

  我们同样可以尝试用5步操作或7步操作来覆盖2-3步的操作,这里的2-3步也好,6步也好,都可以看作是宏定义,效果相似,case数稍有变化。我们可以尝试几个参数,找到覆盖率和工作量的最佳组合。

  6. 人力成本分析

  在整个过程中,需要人力投入的工作只有最初的状态矩阵,对于某个网站来说,这个状态矩阵相对稳定,变化不大,后期维护代价也比较小。

  将状态矩阵拷贝为txt格式,即可作为程序的输入,执行程序即可得到操作序列。将矩阵的title也读入,直接把序列号替换为title,就可以直接当做case来用了。

  有了这样的一组case,我们就可以避免依赖经验的测试或随机测试,又能保证覆盖率了。

  五、 总结

  如上所述,我们用遍历状态矩阵的方法,首先得到了所有2-3步操作组合。这一个“爆炸”的case集包括162个用例。通过case组合的方式,将162个测试用例变成了35+11=46个测试用例,在保证case覆盖率的同时,缩减case数到一个可测试的范围内。

原文转自:http://www.ltesting.net