测试金字塔

一、自动化测试的重要性

公理:要正确交付软件代码,测试是必不可少的。

1. 测试分类

  • 手动测试
  • 自动化测试

2. 何时采用何种测试?

  • 一次性使用的代码
    • 示例:临时脚本或工具
    • 采用手工测试
  • 需要维护的代码
    • 示例:业务代码
      • 警惕陷阱:这个需求后面不会改,先手动测试吧
    • 采用自动化测试
      • 手工测试低效、重复、乏味
      • 自动化测试可以充当代码变更的保护网

二、测试金字塔

Test-Pyramid

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. 契约测试的特征

  • 消费方编写消费方测试,并生成一个协议文件(PactJSON 示例
  • 提供方根据协议文件,编写提供方测试

六、UI 测试

前后端分离的架构下,UI 测试可以是:

  • 纯前端 UI 测试
  • 后端 API 集成测试(cURL 和 Postman 测试的自动化版本)

七、避免重复测试

1. 测试成本

  • 编写和维护测试要花时间
  • 阅读和理解他人的测试也要花时间
  • 执行这些测试也要花时间

2. 基本法则

  • 如果一个更高层级的测试发现了一个错误,并且底层测试全都通过了,那么应该编写一个低层级测试去覆盖这个错误
  • 竭尽所能把测试往金字塔下层赶
  • 删掉那些已经被低层级测试覆盖完全的高层级测试
    • 警惕陷阱沉没成本(不忍删除花了时间精力编写的测试)

八、相关阅读