在讨论如何获得软件可测试性之前,我们需要知道什么是软件可测试性。不妨先看一个生活中简单的例子。有人说,我给你一块黄金,你拿到手的是一块黄澄澄的金属块,但怎么知道是黄金呢?只好用手掂掂,感觉沉甸甸,可能就是黄金,如果是铜则要轻些。但这是不够的,还可以用牙齿咬咬,金子比较软,铜要硬得多。这两项测试做完之后,心中有了点数,但还不能有十足的把握。如果能找到浓硝酸,用这个金属块在石头上划一道痕迹,然后拿棉签蘸一点浓硝酸涂上去。如果划痕还在,说明有金的成分,而且可以根据划痕淡化的程度,大概估算出含金的程度。这样的测试使我们有了信心,但还是不能准确地确定含金量,需要找到更好的办法来测定,这时就要根据化学原理生产这样的仪器。当然,现在有了测试含金量的仪器,如图3-1所示,可以用来确定含金量是9K、10K、12K、14K、18K、22K、24K,即对应的含金量为37.5%、41.66%、50%、58.5%、75%、91.7%、99%以上。
图3-1 黄金含量测试仪
从这个例子可以看到,要测定一样东西,先要了解我们要测试什么样的特性,这些特性是如何体现出来的?如果要判断这些特性是否满足要求,就要明确特性的具体指标。有了这些指标还不够,还需要知道如何测试,或如何获得这些具体指标的结果。这就是我们要讨论的可测试性。
简单地说,百分之百的可测试性,就是在各个层次、各个粒度都可以测试,所有用户需求和系统要求都能(有办法)被验证,或者说,软件中存在的缺陷都能被发现。但实际上,软件可测试性很难达到100%,也就是说,测试的路径覆盖率难以达到100%,这就给测试带来风险,因为软件可测试性是由可观察性、可控制性和可预见性组成的。
1) 可观察性(Observability): 在有限的时间内使用输出描述系统当前状态的能力。
2) 可控制性(Controllability): 在特定的合理操作情况下,在整个配置空间操作(改变)系统的能力,包括状态控制和输出控制。
3) 可预见性(Predictability): 预测系统状态发生变化的能力。
系统具有可观察性意味着一定有输出。有输出,我们才能知道系统当前处于什么状态;如果没有输出,就无法观察系统。系统具有可控制性就表明一定有输入。如果没有输入,我们就无法控制系统,只有通过输入才能控制系统,如图3-2所示。
图3-2 可控制性和可观察性的示意图
如果一个系统缺乏可控制性和可观察性,可通过增加接口的方式,使之产生输出;或增加控制点(可以输入数据),来提高可控制性。如图3-3所示,当模块A缺乏可观察性,而模块B缺乏可控制性,那么我们就在模块A和B之间增加一个接口,使A的状态信息可以在这个接口被获得;同时,增加输入来控制B的状态。或者说,原来模块A直接传给模块B的数据,不是被隐含起来,而是可以显示出来,并且作为接口参数传给模块B。这样,我们就可以通过配置不同的接口参数,来了解模块B的不同表现。
图3-3 改进系统可控制性和可观察性的示意图
但也有一些机构,将可测试性看成是由“可查明性、可隔离性和可诊断性”构成的。可查明性类似于可观察性,而可隔离性和可诊断性要求系统具有可控制性和可预见性,所以从这个角度看,上述的软件可测试性(由可观察性、可控制性和可预见性组成)和这里将可测试性看成可查明性、可隔离性和可诊断性是大同小异的,没有什么本质的区别。
1) 可查明性(Detectability): 相当于可观察性,是指可以查明或了解软件系统某个方面的状况,获得我们想要的有关系统的信息。
2) 可隔离性(Isolatability): 如果发现了软件系统的问题,就能够将当前问题与其他问题隔离开来。隔离问题,要求对系统具有良好的可操作性,并能确定造成问题的影响因素。
3) 可诊断性(Diagnosability): 能找到解决问题的办法,即知道正确的结果是什么,然后有办法消除产生问题的原因。