【准则化的思想】结局由你决定:修改的条件/决策覆盖准则

我们来看另一种价值观。这是一段python代码:

unsubscribed = False
office = "CAN001"
airline = "CA"
if (office == "PEK099" or airline == "CA") and (not unsubscribed):
    print("send email")

这段代码,控制流结构很简单,数据流结构也很简单。比较复杂的只有if语句中的布尔逻辑决策表达式。这个决策表达式,就是这段程序的核心,也是最容易出错的地方。对于这种程序,我们可以说,它的主体结构就是这样的决策表达式。它的主要元素,就是构成决策的每一个条件,比如例子里的office == "PEK099"、airline == "CA"、unsubscribed。

我们将这种价值观准则化,就有了“条件/决策覆盖准则”,也就是要求覆盖所有条件的“真”和“假”两种取值:

当然,要确定一个条件有没有问题,光看它取“真”和“假”的时候决策结果正确与否,是不够的。因为在布尔逻辑决策表达式里面,各个条件可能会互相影响。一个条件写错了,决策结果里可能看不出来,因为错误可能被其它条件掩盖。假设例子里的第一个条件被误写成了office != "PEK099",这样决策表达式就从预期的(A or B) and C变成了(!A or B) and C。如果我们采用“条件/决策覆盖准则”,其实有TFF/FTT/FTF这3个用例就够了。但是这3个用例的实际结果和预期结果一样,发现不了问题。

那怎么办呢?一个简单的想法是,既然条件之间会互相影响,有一些组合可能会掩盖错误,那我就把所有可能的条件取值组合情况,都覆盖到就行了。这就是“条件组合/决策覆盖准则”:

这样做确实可以解决上面的问题,但是同时也引发了一个新的问题,就是测试集的规模容易失控。如果决策里有n 个条件,条件的取值组合就有2^n种,很多时候这种规模都是我们难以接受的。

所以看起来,“条件组合/决策覆盖准则”属于一锅端的做法,有点过于粗放了。实际上,很多时候我们只是希望上面这种错误不要被掩盖。那么,我们能不能在测试选择的时候,做得精细一点,重点选择那些能暴露错误的用例呢?从这个思路出发,就形成了“修改的条件/决策覆盖准则”(MC/DC):

如果测试集满足“修改的条件/决策覆盖准则”,我们就能验证,决策中的每个条件是不是都正确地发挥了作用。这个准则,在航空航天领域有着广泛的应用。​接下来我们要思考的是,怎么样才能落实“每个条件都能显示出对决策结果的独立影响”这个要求呢?

有两个办法,分别是唯一原因型方法和掩盖型方法。唯一原因型方法的思路是,既然是要显示出给定条件对决策结果的独立影响,那我们就找两个组合,这两个组合里,除了给定条件之外,其它条件的取值都一样,但是决策结果不一样。对这两个组合而言,给定条件就是影响决策结果的唯一原因。

比方说(A and B)这个决策:

  ① 对于条件A,我们可以选1号和3号组合,这两个组合里B都是真,A就是影响决策结果的唯一原因,A取真,决策结果就是真;A取假,决策结果就是假。所以,1号和3号两个用例配对,就能够显示出条件A对决策结果的独立影响;

  ② 对于条件B,可以选1号和2号组合,这两个组合里A都是真,B就是影响决策结果的唯一原因,1号和2号两个用例配对,就能够显示出条件B对决策结果的独立影响。

所以,为了满足“修改的条件/决策覆盖准则”,也就是要显示出“每个条件对决策结果的独立影响”,测试集里至少需要包括1号、2号、3号组合这3个用例。用同样的方式,我们可以得到(A 或 B)、(A 异或 B)所需的最小测试集:

如果说,唯一原因型方法是一种正向选择的方法,那么,掩盖型方法就是一种反向排除的方法。排除什么呢?排除那些条件之间存在掩盖的取值组合。就像前面的例子,office == "PEK099"这个条件,在某些组合里就会被掩盖,不能对决策结果产生独立影响。所以,这些组合对满足“修改的条件/决策覆盖准则”没有贡献,应该被排除掉。

来看另一个例子。假设被测程序期望里要求的决策表达式是Z = A and (B xor C)。开发人员写代码的时候把A错写成B了。假定我们设计了这样一个测试集,里面有这样4个用例:

可是,用这样的测试集是不能检出上述缺陷的,因为4个用例的实际结果都和预期结果相符。所以,这个测试集一定是不充分的。

但问题是,在做测试设计的时候,我们不可能预先知道代码里有这个错误。那我们怎么判断自己设计的测试集是不是充分呢?接下来我们尝试用掩盖型方法,来判断这个测试集是否满足“修改的条件/决策覆盖准则”。

掩盖型方法的第一步,是用门符号描述实际决策表达式里的逻辑关系,画出这样一个逻辑图:

第二步,按测试集里的用例顺序,在每一个逻辑门的输入端线上,标记各个用例的输入值:

比如在端线B上,输入值分别是FFTT;在端线C上,输入值分别是TFFT。与门的另一线输入是异或门的输出,所以是TFTF。

第三步,针对每一个逻辑门,消除被掩盖的输入。比方说,异或门的输出是后面与门的输入,如果与门的另一线输入值是假,异或门的输出就无法对决策结果产生影响。所以,我们应该消除异或门上被掩盖的1号、2号输入组合:

第四步,判断每个逻辑门剩下的输入组合,是不是还足以构成满足准则所需的最小测试集。可以看到,异或门现在只剩下TT和TF两个输入组合了,已经不能满足“修改的条件/决策覆盖准则”。

这样我们就知道了我们的测试集并不充分,我们就会想办法去完善已有的测试设计,就更有希望发现上面这个缺陷。在这个例子里,“修改的条件/决策覆盖准则”发挥的作用,就是作为一把标尺,去评估已有测试集的充分性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值