|
软件危机是软件界甚至整个计算机界最热门的话题。为了解决这场危机,软件从业人员、专家和学者做出了大量的努力。现在人们已经逐步认识到所谓的软件危机实际上仅是一种状况,那就是软件中有错误,正是这些错误导致了软件开发在成本、进度和质量上的失控。
软件的质量不仅是体现在程序的正确性上,它和编码以前所做的需求分析,软件设计也密切相关。这时,对错误的纠正往往不能通过可能会诱发更多错误的简单的修修补补,而必须追溯到软件开发的最初阶段。因此,为了保证软件的质量,我们应该着眼于整个软件生存期,特别是着眼于编码以前的各开发阶段的工作。于是,软件测试的概念和实施范围必须扩充,应该包括在整个开发各阶段的复查、评估和检测。由此,广义的软件测试实际是由确认、验证、测试三个方面组成。
在整个软件生存期,确认、验证、测试分别有其侧重的阶段。确认主要体现在计划阶段、需求分析阶段、也会出现在测试阶段;验证主要体现在设计阶段和编码阶段;测试主要体现在编码阶段和测试阶段。事实上,确认、验证、测试是相辅相成的。确认无疑会产生验证和测试的标准,而验证和测试通常又会帮助完成一些确认,特别是在系统测试阶段。
传统的测试计算机软件的策略是从“小型测试”开始,逐步走向“大型测试”。即我们从单元测试开始,然后逐步进入集成测试,最后是有效性和系统测试。在传统应用中,单元测试集中在最小的可编译程序单位——子程序(如,模块、子例程、进程),一旦这些单元均被独立测试后,它被集成在程序结构中,这时要进行一系列的回归测试以发现由于模块的接口所带来的错误和新单元加入所导致的副作用,最后,系统被作为一个整体测试以保证发现在需求中的错误。
面向对象程序的结构不再是传统的功能模块结构,作为一个整体,原有集成测试所要求的逐步将开发的模块搭建在一起进行测试的方法已成为不可能。而且,面向对象软件抛弃了传统的开发模式,对每个开发阶段都有不同以往的要求和结果,已经不可能用功能细化的观点来检测面向对象分析和设计的结果。因此,传统的测试模型对面向对象软件已经不再适用。
1、 面向对象测试模型
面向对象的开发模型突破了传统的瀑布模型,将开发分为面向对象分析(OOA),面向对象设计(OOD),和面向对象编程(OOP)三个阶段。针对这种开发模型,结合传统的测试步骤的划分,我们把面向对象的软件测试分为:面向对象分析的测试,面向对象设计的测试,面向对象编程的测试,面向对象单元测试,面向对象集成测试,面向对象系统测试。
2、 面向对象分析的测试
传统的面向过程分析是一个功能分解的过程,是把一个系统看成可以分解的功能的集合。这种传统的功能分解分析法的着眼点在于一个系统需要什么样的信息处理方法和过程,以过程的抽象来对待系统的需要。而面向对象分析(OOA)是"把E-R图和语义网络模型,即信息造型中的概念,与面向对象程序设计语言中的重要概念结合在一起而形成的分析方法",最后通常是得到问题空间的图表的形式描述。OOA直接映射问题空间,全面的将问题空间中实现功能的现实抽象化。将问题空间中的实例抽象为对象,用对象的结构反映问题空间的复杂实例和复杂关系,用属性和操作表示实例的特性和行为。对一个系统而言,与传统分析方法产生的结果相反,行为是相对稳定的,结构是相对不稳定的,这更充分反映了现实的特性。OOA的结果是为后面阶段类的选定和实现,类层次结构的组织和实现提供平台。因此,对OOA的测试,应从以下方面考虑:
对认定的对象的测试
对认定的结构的测试
对认定的主题的测试
对定义的属性和实例关联的测试
对定义的服务和消息关联的测试
3、 面向对象设计的测试
通常的结构化的设计方法,用的"是面向作业的设计方法,它把系统分解以后,提出一组作业,这些作业是以过程实现系统的基础构造,把问题域的分析转化为求解域的设计,分析的结果是设计阶段的输入"。而面向对象设计(OOD)采用"造型的观点",以OOA为基础归纳出类,并建立类结构或进一步构造成类库,实现分析结果对问题空间的抽象。由此可见,OOD不是在OOA上的另一思维方式的大动干戈,而是OOA的进一步细化和更高层的抽象。所以,OOD与OOA 的界限通常是难以严格区分的。OOD确定类和类结构不仅是满足当前需求分析的要求,更重要的是通过重新组合或加以适当的补充,能方便实现功能的重用和扩增,以不断适应用户的要求。因此,对OOD的测试,应从如下三方面考虑:
对认定的类的测试
对构造的类层次结构的测试
对类库的支持的测试
4、 面向对象编程的测试
典型的面向对象程序具有继承、封装和多态的新特性,这使得传统的测试策略必须有所改变。封装是对数据的隐藏,外界只能通过被提供的操作来访问或修改数据,这样降低了数据被任意修改和读写的可能性,降低了传统程序中对数据非法操作的测试。继承是面向对象程序的重要特点,继承使得代码的重用率提高,同时也使错误传播的概率提高。多态使得面向对象程序对外呈现出强大的处理能力,但同时却使得程序内"同一"函数的行为复杂化,测试时不得不考虑不同类型具体执行的代码和产生的行为。 |
|