单元测试

单元测试不是为了证明代码正确,而是为了控制变化带来的系统性风险


一、单元测试的第一性原理

1. 软件系统的三个不变事实

  1. **变化不可避免**:需求变化、人员流动、环境演进是常态
  2. **人必然会犯错**:复杂系统中不存在零缺陷工程
  3. **复杂度只增不减**:系统一旦上线,复杂度随时间单调上升

单元测试的存在目的,并非“验证正确性”,而是:

在变化发生时,限制错误传播的范围与成本。


二、单元测试在软件工程中的系统位置

1. 风险控制视角

单元测试是软件系统的最小风险防火墙

2. 架构治理视角

单元测试通过“可测性”反向约束架构设计:

不可测试的代码,本质上是架构失控的信号。


三、单元测试的能力分层模型

┌──────────────────────┐│ 风险控制层           │  爆炸半径 / 回归信心├──────────────────────┤│ 架构约束层           │  解耦 / 接缝 / 可替换├──────────────────────┤│ 工程实践层           │  Mock / 覆盖率 / 工具└──────────────────────┘

所有测试实践,都应能在该模型中找到其存在理由。


四、单元测试的核心原则体系

1. AIR 原则(工程稳定性)

2. FIRST 原则(反馈效率)

原则不是规范,而是工程决策的约束条件


五、单元测试的边界与粒度

1. 什么是“单元”

单元并非语法层面的方法或类,而是:

一个职责闭合、行为可预测、依赖可替换的最小行为单元

2. 粒度选择原则


六、单元测试与集成测试的本质差异

维度单元测试集成测试
关注点行为正确性协作正确性
依赖被隔离真实存在
稳定性
反馈速度

单元测试解决局部正确性,集成测试验证系统协作关系


七、单元测试的复杂性来源

  1. **输入复杂性**:一切影响执行路径的因素
  2. **输出复杂性**:所有被修改的状态与副作用
  3. **依赖复杂性**:外部系统、时间、随机性

应对复杂性的唯一方式是:

控制变量,而不是增加断言。


八、测试代码的工程规范

1. 测试即文档

assertUserExists("cxk");

好的测试 API 是业务语言的直接表达。

2. 断言策略

3. 命名原则


九、可测性:架构质量的外显指标

1. 不可测的根因

2. 可测性改造策略

重构不是为了测试,测试是为了暴露重构需求。


十、覆盖率的工程语境

1. 覆盖率的本质

覆盖率是风险可见性指标,而非质量指标。

2. 决策导向的覆盖策略

场景推荐覆盖
核心业务分支 / 条件
工具代码行覆盖
遗留系统新增路径

十一、测试数据构造策略

工具示例:


十二、不同层级代码的测试策略

1. 数据访问层

2. 服务层

3. 工具类


十三、组织与文化视角

1. 单测失败的真实原因

2. 单元测试的真正价值

单元测试不是程序员的负担,而是团队对未来不确定性的集体保险。


结语

单元测试不是一种技术能力,而是一种系统性工程思维

它要求我们:

这,才是单元测试长期存在的根本原因。

关联内容(自动生成)