一、自动化测试的重要性
公理:要正确交付软件代码,测试是必不可少的。
1. 测试分类
- 手动测试
- 自动化测试
2. 何时采用何种测试?
- 一次性使用的代码
- 示例:临时脚本或工具
- 采用手工测试
- 需要维护的代码
- 示例:业务代码
- 警惕陷阱:这个需求后面不会改,先手动测试吧
- 采用自动化测试
- 手工测试低效、重复、乏味
- 自动化测试可以充当代码变更的保护网
- 示例:业务代码
二、测试金字塔
1. 核心原则
- 编写不同粒度的测试
- 层次越高,编写的测试应该越少
2. 反模式
三、单元测试
1. Why
为什么要多写单元测试?
- 规模小(关注点聚焦,更容易编写)
- 执行快(最小化依赖,运行成本低)
2. What
何为一个单元?
- 面向过程/函数式:一个函数
- 面向对象:一个方法、一个类
群居和独居
- 独居:隔离所有外部依赖
- 群居:只隔离那些执行慢或者副作用大的依赖(比如数据库、外部服务等)
3. How
测试什么?
- 通常只测试一个类的公共方法
- 如果一个类复杂到需要测试它的私有方法
- 考虑从设计上拆分这个类,把这些私有方法变成另一个类的公共方法
测试结构(Arrange-Act-Assert 或者 Given-When-Then)
- 准备测试数据
- 调用被测方法
- 断言返回的是期待的结果
四、集成测试
测试应用和所有外部依赖的集成。
常见的外部依赖有:
- 数据库(如 MySQL、Redis、Elasticsearch)
- 消息队列(如 Kafka)
- 外部服务(如 SendCloud、S3)
- 进行契约测试
- 编写消费方测试
- 同时为外部服务编写提供方测试?
- 通常不需要。因为成熟的服务提供方往往会对 API 做版本控制;而且在废弃旧版本 API 之前,也会通知到服务消费方。
- 进行契约测试
五、契约测试
1. 不适用场景
公共服务的提供方和消费方之间。
2. 适用场景
内部微服务的提供方和消费方之间。
提供方和消费方之间的通信方式,常见的有:
- RPC 接口
- HTTP/JSON
- gRPC
- 异步事件
3. 契约测试的特征
六、UI 测试
前后端分离的架构下,UI 测试可以是:
- 纯前端 UI 测试
- 后端 API 集成测试(cURL 和 Postman 测试的自动化版本)
七、避免重复测试
1. 测试成本
- 编写和维护测试要花时间
- 阅读和理解他人的测试也要花时间
- 执行这些测试也要花时间
2. 基本法则
- 如果一个更高层级的测试发现了一个错误,并且底层测试全都通过了,那么应该编写一个低层级测试去覆盖这个错误
- 竭尽所能把测试往金字塔下层赶
- 删掉那些已经被低层级测试覆盖完全的高层级测试
- 警惕陷阱:沉没成本(不忍删除花了时间精力编写的测试)