【枚举的思想】等价类划分法,其实是被阉割的分割测试法

如果想判定现实和理想是不是完全一致,我们就需要枚举测试输入空间中的每一个点。为什么呢?因为理想和现实,跟每一个测试输入点都有关。“枚举”并不是“机械地穷举”。枚举的思想具有两个鲜明的特征:

  ①第一,强调“聪明的枚举”,在枚举的同时尽可能压缩测试集的规模,控制测试成本。典型的例子就是组合测试;

  ②第二,这种压缩必须是“无损”的,避免对正确性判定造成影响。

在进行枚举之前,如果我们已经知道,测试输入空间中有一部分点,对应的理想是一样的,对应的现实也是一样的,那么从测试的角度讲,这些点就没什么区别,我们只需要测试其中任意一个点。这样,我们就实现了枚举测试的“无损压缩”。这就是分割测试的基本思路。

如果我们能找出这样的测试输入点,我们就可以把整个测试输入空间分割成一些子空间。

在每个子空间里,被测对象以同样的方式响应所有测试输入点,而且响应方式要么都符合期望,要么都不符合期望。这样的子空间,我们叫做“同质子空间”。同质子空间里的所有测试输入点,可以认为都是等价的。

下面我们看一个例子,来说明分割测试的具体过程。假设我们的被测对象是一个计算产品售价的程序,它的期望是这么描述的:“一家公司生产X和Y两种产品,X单价为5元,Y单价为10元。订单中包含对X和Y的订购数量。折扣方式是:如果总价超过200元,折扣5%;如果总价超过1000元,折扣20%;如果订购X的数量超过30件,则额外再折扣10%。程序输入是X和Y两种产品分别的订购数量,输出是这两种产品的折后价之和,并向上取整。”

这是程序的代码实现:

  public double discount_invoice(int x, int y) {
    int discount1 = 0;
    int discount2 = 0;
    if (x <= 30)
      discount2 = 100;
    else
      discount2 = 90;
    int sum = 5 * x + 10 * y;
    if (sum <= 200)
      discount1 = 100;
    else if (sum <= 1000)
      discount1 = 95;
    else
      discount1 = 80;
    return (Math.ceil(sum * discount1 * discount2 / 10000));
  }

以及对应的流程图:

代码逻辑很简单,基本就是按照期望的要求,先根据X的数量计算discount2,再根据总价计算discount1,最后输出总的折后价。那么,针对这样一个程序,我们怎样开展分割测试呢?

有三个步骤。第一步,按程序流程图中的路径,对测试输入空间进行分割,要求在分割出的每个子空间里,所有的测试输入点触发的执行路径都一样。执行路径一样,就意味着程序对这些点的响应方式一样。示例程序里一共有6条路径:

我们可以根据触发各条路径的条件,把测试输入空间划分成A/B/C/D/E/F这样6个子空间:

第二步,按期望信息对测试输入空间进行分割,要求划分出的每个子空间中,所有测试输入点的期望处理方式都一样。根据期望的描述,我们可以分析出来,订购X产品的数量是否超过30件,期望的处理方式是不同的;另外,总价在200以下、在200到1000之间、在1000以上,也各自有相应的期望处理方式;最后,x和y都是订购产品的数量,应该都是大于等于0的,如果小于0就应该报错。这样,我们就可以把测试输入空间分割成7个子空间:

第三步,把第一步、第二步得到的子空间进行交叉。所谓“交叉”,就是取分割线的并集,示意如下:

刚才在第一步里,我们分割出了6个子空间,在第二步里,分割出了7个子空间。交叉以后,可以得到12个子空间:

这些才是真正的“同质子空间”。

在每一个同质子空间里,所有的测试输入点都对应着相同的期望处理方式,而且都对应着同一条程序执行路径,我们只需要从中任意选一个点来测试,就能够判定这条执行路径的处理结果是不是符合期望。测试结果显示,只有A/B/C/D/E/F这几个子空间的处理结果是符合期望的。实际上,第一步、第二步分割结果的差异,已经预示了程序中很可能存在缺陷——输入变量x和y都应该是非负值,但程序里没做这个判断。

在我们实际的项目里,要完成第一步,也就是按程序路径划分子空间,经常是很困难的,因为被测程序的路径数量都非常大,路径条件的求解也是个很大的问题。所以我们往往只做第二步,也就是只根据需求、规约这样一些期望信息,来划分子空间。这时候,分割测试就被阉割成了纯黑盒的等价类划分法

当然,等价类划分法是可以用的,但我们需要清醒地认识到,等价类划分法的合理性是基于一个重要的假设,也就是第一步和第二步的分割结果是一致的。显然这个假设不一定成立。我们常常遇到这样的问题:两组数据本来应该用同样的方式来处理,实际触发的却是不同的程序路径。

​仅仅根据期望来划分的所谓等价类,其实并不一定等价。要想真正贯彻枚举的思想,做到无损压缩,我们就必须全面考察理想和现实两方面的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值