软件缺陷
- Error: 人的错误行为导致软件中出现不希望或不可接受的内部状态
- Fault: 软件运行时出现不希望或不可接受的状态
- Failure: 软件运行时产生了不希望或不可接受的外部行为结果
- incident: 软件运行中出现了与失效类似的现象
- anomaly: 软件运行中出现了未预期的现象
- Vulnerability: 能被利用进行攻击的代码缺陷
- variance: 软件中于要求不一致处
- Defect (Bug): 存在于软件生存期中哪些不希望或不可接受的偏差
- 错误
- 遗漏
- 额外实现
- 因需求产生的缺陷最多
- 在软件生存期中,缺陷发现和清除的越晚,需付出的代价越大
- 技术手段
- 需求/设计
- 自然语言:评审
- 半形式语言(UML):评审+验证
- 形式语言:自动验证
- 代码
- 评审
- 分析:程序分析
- 验证:模型检验、推理证明
- 可执行系统
- 测试:白盒、黑河、灰盒
- 运行时验证
- 监控/容错
- 需求/设计
程序分析
- 静态分析与动态分析
- 工具:Coverity, PCLint, Clang, Klocwork
软件测试
- 测试活动:标识 - 设计 - 开发 - 执行 - 比较
- 功能测试与非功能测试
黑盒方法
- 将测试对象看做黑色盒子,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明
- 穷尽测试:黑盒测试中穷尽所有可能输入条件和输出条件(不可能)
等价类划分法
- 将程序输入域划分为若干部分,每个子集中选取少数具有代表性的数据作为测试用例
- 有效等价类:检验程序是否实现了规格说明中预先规定的功能和性能
- 无效等价类:无意义的、不合理的输入数据所构成的集合
- 标准等价类测试:不考虑无效数据值,测试用例使用每个等价类中的一个值
- 健壮等价类测试:对无效输入,一个测试用例有一个无效值,其他值均取有效值
- 需要花费精力定义无效测试用例的期望输出
- 对强类型的语言没有必要考虑无效的输入
- 测试用例设计
-
构建等价类表
-
为每个等价类规定唯一编号
-
设计一个新的测试用例,使它能够尽量覆盖尚未覆盖的有效等价类;直到全覆盖
-
设计一个新的测试用例,使它仅覆盖一个尚未覆盖的无效等价类;直到全覆盖
-
边界值分析法
- 在等价类的边界以及两侧的情况设计测试用例
因果图法
- 方法步骤
- 根据说明书确定因(输入条件)和过(输出结果),画出因果图
- 将因果图转换为判定表
- 为判定表每一列设计一个测试用例
白盒方法
- 循环度量
逻辑覆盖与基本路径方法
- 语句覆盖:选取足够多的测试数据,使被测试程序中每个语句至少执行一次
- 判定覆盖:选取足够多的测试数据,使被测试程序中不仅每个语句至少执行一次,而且每个判定的每种可能的结果都至少执行一次
- 条件覆盖:选取足够多的测试数据,使被测试程序中不 仅每个语句至少执行一次,而且每个判定表达式中的每个条件都取到各种可能的结果
- 判定/条件覆盖:选取足够多的测试数据,使得判定表达式中的每个条件都取到各种可能的结果,而 且每个判定表达式也都取到各种可能的结果
- 条件组合覆盖:选取足够多的测试数据,使得判定表达式中条件的各种可能组合都至少出现一次
- 路径覆盖:选取足够多的测试数据,使得程序的每条可能路径都至少执行一次(若程序图中有环, 则每个环至少经过一次)
- 路径选择
- 嵌套型:$n$ 个判定语句,$n+1$ 个测试用例
- 连锁型:$n$ 个判定语句,$2^n$ 个测试用例
- 循环路径选择
- 简单循环
- 连锁循环
- 嵌套循环
- 非结构循环
软件验证
- 形式化方法
- 规约
- 验证:定理证明、模型检验
- Kripke Model