跳转至

Chapter 24: Testing Object-Oriented Applications

24.1 面向对象应用测试概述

  1. 为了充分测试 OO 系统,必须完成三件事:
    • 扩大测试的定义,使其包含应用于面向对象分析(OO Analysis)和面向对象设计(OO Design)模型的错误发现技术 。
    • 显著改变单元测试(Unit Testing)和集成测试(Integration Testing)的策略 。
    • 测试用例的设计必须考虑到OO软件的独特特性 。
  2. 测试 OO 模型

    测试和评审 OO 分析和设计模型特别有用,因为在分析、设计和编写代码等阶段会遇到相同的语义结构(如类、属性、操作、消息) 。因此,在分析阶段发现类属性定义的错误,可以避免该问题在后续设计、代码或下一次迭代中产生副作用 。

  3. OO 模型的正确性

    • 在分析和设计阶段,语义正确性(Semantic Corrctness)可以根据模型对现实世界问题域的一致性进行评估 。
    • 如果模型准确反映了现实世界,则它是语义正确的 。
    • 应将模型提交给领域专家评审,检查类定义和层次结构的遗漏或歧义 。
    • 评估类关系,以确定其是否准确反映了现实对象间的连接 。
  4. 类与模型的一致性
    • 重新审视 CRC 模型和对象关系模型。
    • 检查每张 CRC 索引卡的描述,以确定每个被委托的职责是否属于协作者的定义范围。
    • 反向检查连接,确保每个被请求服务的协作者都收到了来自合理来源的请求。
    • 使用上一步中检查过的反向连接,判断是否需要其他类,或者职责是否在类之间得到了恰当的分配。
    • 判断那些被广泛请求的职责是否可以合并为单一职责。

24.2 面向对象测试的策略

  1. 单元测试(Unit Testing):测试单个类
    • 最小的可测试单元是封装的类(Encapsulated Class)
    • 不能孤立测试单个操作,而必须将其作为类的一部分进行测试 。
  2. 集成测试(Integration Testing):测试多个类如何协作
    • 基于线程的测试(Thread-based Testing):集成响应系统某个输入或事件所需的一组类 。
    • 基于使用的测试(Use-based Testing):先测试独立类(几乎不使用其他类的类),再测试依赖类(依赖其他类的类)。
    • 簇测试(Cluster Testing):通过设计测试用例,来检验一组协作类(通过检查 CRC 和对象关系模型确定)在协作过程中的错误。
  3. 确认测试(Validation Testing):测试整个系统是否实现了期望功能
    • 不再考虑类与类之间的连接细节
    • 可以使用用例进行测试
    • 传统的黑盒测试方法可用于驱动确认测试

24.3 面向对象测试的方法

  1. Berard 方法

    Berard 提出了以下方法:

    • 每个测试用例应有唯一标识,并明确关联到待测试的类;
    • 应说明测试的目的;
    • 应为每个测试制定一系列测试步骤,其中应包含:
      • 待测试对象的一组指定状态
      • 将要作为测试序列而执行的一组消息和操作
      • 测试对象时可能出现的一组异常
      • 一组外部条件(即软件外部环境的变化,按顺序进行组织)
      • 有助于理解或执行测试的补充信息。
    • 基于故障的测试(Fault-based Testing)
    • 测试人员寻找可能存在的故障。为了确定这些故障是否存在,设计测试用例来检验设计或代码。
    • 类测试与类层次结构(Class Testing)
    • 继承并不能免除对所有派生类进行彻底测试的必要性。
    • 基于场景的测试设计(Scenario-based Test Design)
    • 基于场景的测试专注于用户做了什么,而不是产品做了什么。这意味着捕获用户需要执行的任务(通过用例),然后将这些任务及其变体作为测试用例应用。
    • 随机测试(Random Testing)
    • 确定适用于类的操作
    • 定义操作的使用约束
    • 确定一个最小测试序列(定义类(对象)最小生命历程的操作序列)
    • 生成各种随机(但有效)的测试序列
    • 执行其他(更复杂的)类实例生命历程
    • 划分测试(Partition Testing)

    以类似于传统软件的等价划分的方式,减少测试类所需的测试用例数量。

    • 基于状态的划分(State-based):根据操作改变类状态的能力对操作进行分类和测试。
    • 基于属性的划分(Attribute-based):根据操作所使用的属性对操作进行分类和测试。
    • 基于类别的划分(Category-based):根据每个操作执行的通用功能对操作进行分类和测试。
    • 类间测试(Inter-Class Testing)
    • 从客户类开始,随机生成操作序列,每发出一条消息就追到对应的服务器类,看它还会发什么消息,一层层追下去,把所有协作的类都串起来测试。
    • 行为测试(Behavior Testing)
    • 设计的测试应覆盖所有状态。也就是说,操作序列应使得类遍历所有允许的状态。