2.2.1 黑盒测试
黑盒测试是一种重要的测试策略,又称为数据驱动的测试或输入/输出驱动的测试。使用这种测试方法时,将程序视为一个黑盒子。测试目标与程序的内部机制和结构完全无关,而是将重点集中放在发现程序不按其规范正确运行的环境条件。
在这种方法中,测试数据完全来源于软件规范(换句话说,不需要去了解程序的内部结构)。
如果想用这种方法来发现程序的所有错误,判定的标准就是“穷举输入测试”,将所有可能的输入条件都作为测试用例。为什么这样做?比如说在三角形测试的程序中,试过了三个等边三角形的测试用例,这不能确保正确地判断出所有的等边三角形。程序中可能包含对边长为3842,3842,3842的特殊检查,并指出此三角形为不规则三角形。由于程序是个黑盒子,因此能够确定此条语句存在的惟一方法,就是试验所有的输入情况。
要穷举测试这个三角形程序,可能需要为所有有效的三角形创建测试用例,只要三角形边长在开发语言允许的最大整数值范围内。这些测试用例本身就是天文数字,但这还绝不是所谓穷尽的;当程序指出-3,4,5是一个不规则三角形或2,A,2是一个等腰三角形时,问题就暴露出来了。为了确保能够发现所有这样的错误,不仅得用所有有效的输入,而且还得用所有可能的输入进行测试。因此,为了穷举测试三角形程序,实际上需要创建无限的测试用例,这当然是不可能的。
如果测试这个三角形程序都这么难的话,那么要穷举测试一个稍大些的程序的难度就更大了。设想一下,如果要对一个C++编译器进行黑盒穷举测试,不仅要创建代表所有有效C++程序的测试用例(实际上,这又是一个无穷数),还需要创建代表所有无效C++程序的测试用例(无穷数),以确保编译器能够检测出它们是无效的。也就是说,编译器必须进行测试,确保其不会执行不应执行的操作—如顺利地编译成功一个语法上不正确的程序。
如果程序使用到数据存储,如操作系统或数据库应用程序,这个问题会变得尤为严重。举例来说,在航班预定系统这样的数据库应用程序中,诸如数据库查询、航班预约这样的事务处理需要随上一次事务的执行情况而定。因此,不仅要测试所有有效的和无效的事务处理,还要测试所有可能的事务处理顺序。
上述讨论说明,穷举输入测试是无法实现的。这有两方面的含义,一是我们无法测试一个程序以确保它是无错的,二是软件测试中需要考虑的一个基本问题是软件测试的经济学。也就是说,由于穷举测试是不可能的,测试投入的目标在于通过有限的测试用例,最大限度地提高发现的问题的数量,以取得最好的测试效果。除了其他因素之外,要实现这个目标,还需要能够窥见软件的内部,对程序作些合理但非无懈可击的假设(例如,如果三角形程序将2,2,2视为等边三角形,那就有理由认为程序对3,3,3也作同样判断)。这种思路将形成本书第4章中测试用例设计策略的部分方法。