软件缺陷

  • Error: 人的错误行为导致软件中出现不希望或不可接受的内部状态
  • Fault: 软件运行时出现不希望或不可接受的状态
  • Failure: 软件运行时产生了不希望或不可接受的外部行为结果
  • incident: 软件运行中出现了与失效类似的现象
  • anomaly: 软件运行中出现了未预期的现象
  • Vulnerability: 能被利用进行攻击的代码缺陷
  • variance: 软件中于要求不一致处
  • Defect (Bug): 存在于软件生存期中哪些不希望或不可接受的偏差
    • 错误
    • 遗漏
    • 额外实现
  • 因需求产生的缺陷最多
  • 在软件生存期中,缺陷发现和清除的越晚,需付出的代价越大
  • 技术手段
    • 需求/设计
      • 自然语言:评审
      • 半形式语言(UML):评审+验证
      • 形式语言:自动验证
    • 代码
      • 评审
      • 分析:程序分析
      • 验证:模型检验、推理证明
    • 可执行系统
      • 测试:白盒、黑河、灰盒
      • 运行时验证
      • 监控/容错

程序分析

  • 静态分析与动态分析
  • 工具:Coverity, PCLint, Clang, Klocwork

软件测试

  • 测试活动:标识 - 设计 - 开发 - 执行 - 比较

软件测试分类

  • 功能测试与非功能测试

黑盒方法

  • 将测试对象看做黑色盒子,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明
  • 穷尽测试:黑盒测试中穷尽所有可能输入条件和输出条件(不可能)

等价类划分法

  • 将程序输入域划分为若干部分,每个子集中选取少数具有代表性的数据作为测试用例
  • 有效等价类:检验程序是否实现了规格说明中预先规定的功能和性能
  • 无效等价类:无意义的、不合理的输入数据所构成的集合
  • 标准等价类测试:不考虑无效数据值,测试用例使用每个等价类中的一个值
  • 健壮等价类测试:对无效输入,一个测试用例有一个无效值,其他值均取有效值
    • 需要花费精力定义无效测试用例的期望输出
    • 对强类型的语言没有必要考虑无效的输入
  • 测试用例设计
    • 构建等价类表

      等价类表例

    • 为每个等价类规定唯一编号

    • 设计一个新的测试用例,使它能够尽量覆盖尚未覆盖的有效等价类;直到全覆盖

    • 设计一个新的测试用例,使它仅覆盖一个尚未覆盖的无效等价类;直到全覆盖

边界值分析法

  • 在等价类的边界以及两侧的情况设计测试用例

因果图法

  • 方法步骤
    • 根据说明书确定因(输入条件)和过(输出结果),画出因果图
    • 将因果图转换为判定表
    • 为判定表每一列设计一个测试用例

白盒方法

  • 循环度量

逻辑覆盖与基本路径方法

  • 语句覆盖:选取足够多的测试数据,使被测试程序中每个语句至少执行一次
  • 判定覆盖:选取足够多的测试数据,使被测试程序中不仅每个语句至少执行一次,而且每个判定的每种可能的结果都至少执行一次
  • 条件覆盖:选取足够多的测试数据,使被测试程序中不 仅每个语句至少执行一次,而且每个判定表达式中的每个条件都取到各种可能的结果
  • 判定/条件覆盖:选取足够多的测试数据,使得判定表达式中的每个条件都取到各种可能的结果,而 且每个判定表达式也都取到各种可能的结果
  • 条件组合覆盖:选取足够多的测试数据,使得判定表达式中条件的各种可能组合都至少出现一次
  • 路径覆盖:选取足够多的测试数据,使得程序的每条可能路径都至少执行一次(若程序图中有环, 则每个环至少经过一次)
  • 路径选择
    • 嵌套型:$n$ 个判定语句,$n+1$ 个测试用例
    • 连锁型:$n$ 个判定语句,$2^n$ 个测试用例
  • 循环路径选择
    • 简单循环
    • 连锁循环
    • 嵌套循环
    • 非结构循环

软件验证

  • 形式化方法
    • 规约
    • 验证:定理证明、模型检验
  • Kripke Model