J04 测试
J04 测试
验证与确认 (Vérification et Validation)
- 验证 (Vérification)
- 确认我们是否正确地制作了产品。
- 软件是否符合其规格说明?
- 确认 (Validation)
- 确认我们是否制作了正确的产品。
- 软件是否满足用户需求?
验证方法 (Méthodes de vérification)
- 检查 (Inspection)
- 静态测试,包括规格说明和代码的审查。
- 测试 (Test)
- 动态测试,通过输入数据运行代码。
符号验证 (Vérification symbolique)
- 抽象执行,生成输入数据或验证特定点(如代码覆盖、计算精度等)。
形式验证 (Vérification formelle)
- 基于证明或模型检测(Model Checking)。
为什么要测试?(Pourquoi tester ?)
- 研究表明,设计阶段修复错误的成本与生产阶段相比,成本比为 1:100。
- 在开发 NASA 卫星嵌入式软件时,测试占开发预算的 80%(管理信息系统的标准是 35%)。
测试的难点 (Difficultés des tests)
- 测试是一种部分验证的方法。
- 有时被认为是负面方法:旨在检测错误,而非构建性开发活动的一部分。
术语 (Terminologie)
- 异常 (Anomalie)
- 系统行为不符合规格说明。
- 缺陷 (Défaut)
- 代码片段在运行时可能导致异常。
- 错误 (Erreur)
- 导致缺陷的人为行为。
不同类型的测试 (Les différents tests)
- 单元测试 (Tests unitaires)
- 测试单个组件的独立行为。
- 组件可以是一个函数或方法。
- 隔离测试:组件需要在完全隔离的环境下测试(不访问文件、数据库等)。
- 如果组件依赖于其他服务,使用桩 (stubs) 或模拟对象 (mock objects) 来代替。
- 集成测试 (Tests d'intégration)
- 非回归测试 (Tests de non régression)
- 名义测试 (Tests nominaux)
- 鲁棒性测试 (Tests de robustesse)
- 性能测试 (Tests de performance)
输入数据的选择 (Choix des données d'entrée)
- 基于规格说明
- 功能性测试:黑盒测试方法。
- 数据选择基于被测模块的描述。
- 难点:数据集合通常是无限的。
- 基于代码
- 结构性测试:白盒测试方法。
- 数据选择需要覆盖模块中的所有代码路径至少一次。
- 难点:组合爆炸问题(combinatorial explosion)。
黑盒测试 (Test boîte noire)
- 利用规格说明,根据输入值预测输出结果。
- 极限值测试(Valeurs limites)。
- 空数组。
- 仅有一个元素的数组(目标元素存在/不存在)。
- 第一个或最后一个元素为目标。
- 将输入划分为等价类,每类至少选择一个代表值。
- 分类测试:
- 目标元素存在。
- 目标元素不存在。
- 不同大小的数组。
白盒测试 (Test boîte blanche)
- 基于代码知识的测试。
- 执行每条指令和每个路径至少一次。
- 构建控制流图,包括:
- 节点:表示指令。
- 边:表示分支。
圈复杂度 (Complexité cyclomatique)
- 独立路径的数量,计算方式如下:
- 边数 - 节点数 + 2。
- 图的区域数。
- 决策节点数 + 1。
- 下界:执行所有独立路径所需的最少测试次数。
- 上界:执行所有指令所需的最大测试次数。
JUnit 单元测试 (Tests unitaires en Java)
1 | import org.junit.jupiter.api.Test; |
JUnit 断言 (Assertions)
assertEquals()
:验证两个对象相等。assertSame()
:验证两个引用是否指向同一对象。assertNull()
:验证对象是否为 null。assertTrue()
:验证表达式是否为真。assertArrayEquals()
:验证两个数组是否相等。assertThrows()
:验证是否抛出异常。assertTimeout()
:验证执行是否在规定时间内完成。
组件隔离 (Isoler un composant)
- 单元测试的组件不应依赖其他组件。
- 使用模拟对象(Mocks)代替实际依赖。
- 示例框架:Mockito。
验证不变量、前置条件或后置条件
- 使用
assert
语句。
1 | assert tableau != null; |
启用断言
- 通过
java -ea
命令。
测试驱动开发 (Développement piloté par les tests, TDD)
- 一种先编写单元测试再编写代码的方法。
TDD 的步骤
- 建模测试对象(了解其公开方法)。
- 编写测试对象的框架代码(方法声明)。
- 循环迭代:
- 编写测试。
- 执行测试(应失败)。
- 编写足够的业务代码以通过测试。
红绿重构循环 (Red, Green, Refactor)
- 红色:测试失败。
- 绿色:测试通过。
- 重构:优化代码。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Raphael's Home!