软件测试是软件开发的重要、必要部分,是通过找出缺陷和问题评估产品质量并间接改进产品质量的手段。从软件工程的观点看,预防程序问题要比改正问题重要得多,因此,必须首先把软件测试看做是检验预防程序错误的机制是否有效的主要手段,同时又是找出程序异常的手段。
  从一段对话谈起
  甲、乙、丙三人对“所有奇数都是质数”这个假设进行测试。
  甲说:“3是质数,5是质数,7是质数。看起来这个假设没错。”
  乙说:“3是质数,5是质数,7是质数,9是质数,11是质数……”
  丙说:“错!9是一个非质数奇数。”
  软件测试是从一个错误陈述(“系统能正常运行”)开始,从无限种可能中选出与该陈述矛盾的输入。必须避免甲犯过的错误(没有验证合适的值),也要避免犯乙犯过的错误(验证了合适的值,但是没有发现矛盾之处),需要像丙那样,用小工作量找出合适的反例。
  IEEE把软件测试定义为:从通常是无限大的执行域中恰当地选取一组有限测试用例,对照程序已经定义的预期行为,动态地检验程序的行为。
  从这个定义可以看出软件测试的四个特点:首先是“动态”,软件测试总要通过一组输入执行程序。但是,单靠输入值并不总能充分地确定一个测试,因为对于复杂、非确定的系统,由于系统会处于不同的状态,因此对于同样的输入可能产生不同的响应。所以,特定的输入通常还要指定系统的特定状态。其次是“有限”,在测试中实际能够观察的执行数量是有限的。测试永远都意味着有限资源和计划进度与本质上是无限测试需求之间的折衷:正是这种矛盾带来了大家经常提到的技术(测试充分性评判准则)和管理(测试工作量估计)两个方面的测试问题。接着是“选取”,很多测试手段的本质区别是如何选择有限的测试集。针对特定条件确定合适的选取准则是一个非常复杂的问题,在实践中需要运用风险分析技术和测试工程专门知识。后是“预期”,必须能够确定所观察到的程序执行输出是不是可接受的,否则测试工作是无用的。
  软件测试通常要在不同层次上执行,大体上划分为三大阶段:单元测试、集成测试和系统测试。单元测试检验独立软件模块的机能,软件模块可以是独立子程序,也可以是由紧密相关的数个单元组成的较大构件,单元测试一般需要对被测代码进行访问并借助调试工具的支持,并且可能需要被测代码编程人员的介入;集成测试检验系统各部件间的交互性。经典的集成测试策略有自顶向下或自底向上两种,用于传统的、分级的结构化软件系统。现代的集成测试策略更多是结构驱动的,这意味着对软件部件或子系统的集成是基于确定的功能线程,因此集成测试是一个连续活动,在每一阶段测试人员必须抽象出低一级的情况并集中于正在处理的这一级的状况;系统测试关注的则是整个系统的行为,它需要将系统与非功能性系统需求进行比较,非功能性系统需求指系统的安全性、速率、精确性、可靠性等。系统与其它软件、应用程序、硬件设备或操作环境的外部接口评估也在系统测试中进行。
  测试技术分类
  从软件生产发达来看,20世纪60年代,软件测试主要以代码调试为主;70年代主要以演示软件系统的正确性为主;80年代到90年代中期,主要以检查程序错误为主;90年代中期以后,软件测试开始更注重软件质量特性的整体评估。目前软件测试主要的目标是评估软件功能,但一般也要测试软件的非功能属性。