E2E 测试

E2E 测试(End-to-End Testing,端到端测试),本质就是:

👉 从用户视角出发,完整走一遍真实业务流程,验证整个系统是否正常工作。

它不是测某个函数、某个接口,而是测:

整个系统链路:前端 → 后端 → 数据库 → 外部服务

以“发评论”为例:
用户在微博发一条评论:

1. 前端输入评论
2. 调用评论接口
3. 后端做敏感词过滤
4. 写入 MySQL
5. 更新 Redis 缓存
6. 发通知给作者
7. 前端刷新评论列表

在 E2E 测试中,它会模拟真实用户:

打开页面 → 输入评论 → 点击发送 → 检查页面是否出现新评论

并验证:

  • 评论是否真的写入数据库
  • 页面是否更新
  • 缓存是否正确刷新
  • 通知是否发送成功

E2E 测试和其他测试的区别

测试类型 测什么 举例
Unit Test(单元测试) 一个函数 计算热度函数
Integration Test(集成测试) 模块之间 Service + DB
E2E 测试 整个系统流程 发评论、下单、登录

E2E 测试关注的是“用户行为”
不是这样:

测试 postComment() 方法对不对

而是这样:

用户点击“发送评论”按钮 → 是否真的发成功

👉 重点是:

像真实用户一样操作系统

E2E 测试的特点
✔ 1️⃣ 覆盖范围最大

整个系统链路

✔ 2️⃣ 最接近真实用户
👉 模拟浏览器行为

✔ 3️⃣ 最慢(很重要)
因为:

  • 要跑整个系统
  • 要访问数据库
  • 要走网络

✔ 4️⃣ 最容易失败
因为依赖太多:

  • 网络
  • DB
  • 缓存
  • 外部服务

常见工具
常见 E2E 测试工具:

  • Selenium
  • Cypress
  • Playwright

E2E 测试的优缺点
✔ 优点

  • 能发现“整体流程问题”
  • 模拟真实用户
  • 防止上线大 bug

❌ 缺点

  • 不稳定(flaky test)
  • 排查困难
  • 成本高

即:

单元测试:点
集成测试:线
E2E测试:面

总结

👉 E2E 测试就是模拟真实用户,从头到尾走完整业务流程,验证整个系统是否正常运作。

集成测试

集成测试(Integration Testing),本质是:

👉 验证“多个模块/服务组合在一起工作是否正确”

它介于单元测试和 E2E 测试之间,是非常关键的一层。

假设“发评论”流程:

Controller → Service → DAO → Redis → MySQL → MQ

集成测试

“评论服务 + 数据库 + Redis 是否能一起正常工作”

调用 CommentService.addComment()

检查:
✔ MySQL 是否插入成功
✔ Redis 计数是否更新
✔ 返回结果是否正确

👉 注意:

  • ❌ 不模拟用户浏览器
  • ❌ 不测整个系统UI
  • ✔ 测的是“后端模块协作”

集成测试的特点
✔ 1️⃣ 比单元测试真实
因为:

  • 用真实 DB
  • 用真实 Redis
  • 不 mock 或少 mock

✔ 2️⃣ 比 E2E 更轻量
因为:

  • 不跑 UI
  • 不模拟浏览器
  • 只测试后端链路

✔ 3️⃣ 更容易发现“接口问题”
比如:

  • 字段不匹配
  • SQL错误
  • Redis key设计错误

一个典型例子(评论系统)
✔ 测试目标:

发表评论 + 计数更新 + 缓存更新

✔ 测试流程:

1. 调用 addComment()
2. 检查 MySQL 是否插入
3. 检查 Redis counter 是否 +1
4. 检查缓存是否被删除

集成测试常见工具
Java 生态:

  • JUnit + Spring Test
  • Testcontainers(很重要)
  • Mockito(部分 mock)

👉 Testcontainers(重点)
它可以:

👉 启动真实 MySQL / Redis / Kafka 容器做测试

集成测试的核心价值

👉 保证“系统不是拼起来就坏掉”

因为现实问题是:

  • 单元测试都通过
  • 但一连 DB 就挂
  • 一连 Redis 就错

👉 集成测试就是防这个的

API 测试

API 测试(API Testing),本质是:

👉 直接测试“接口是否按预期工作”,而不是测试内部代码逻辑

它处在测试体系的中间层:比单元测试更接近真实业务,比 E2E 测试更轻量。

👉 API测试 = 通过 HTTP 请求调用接口,验证返回结果是否正确

以“发评论接口”为例:

POST /api/comment/add

请求:

{
  "postId": 1001,
  "content": "hello"
}

✔ API测试会验证:
1️⃣ 接口是否成功

HTTP 200 / 400 / 500 是否正确

2️⃣ 返回数据是否正确

{
  "code": 0,
  "data": {
    "commentId": 123
  }
}

3️⃣ 业务结果是否正确

  • 数据是否写入数据库
  • Redis 是否更新
  • 返回值是否符合规则

API 测试常见形式(代码)
Java + RestAssured:

given()
    .contentType("application/json")
    .body(request)
.when()
    .post("/api/comment/add")
.then()
    .statusCode(200)
    .body("code", equalTo(0));

✔ 或 MockMvc(Spring)

mockMvc.perform(post("/api/comment/add"))
       .andExpect(status().isOk());

✔ 或 Postman
直接点按钮发请求

API测试的特点
✔ 1️⃣ 通过 HTTP 调用
👉 和真实前端调用方式一致

✔ 2️⃣ 不测 UI
👉 没有浏览器,不是 E2E

✔ 3️⃣ 可以用真实或 mock 数据库
👉 取决于测试类型

✔ 4️⃣ 运行快
比 E2E 快很多

API测试的价值
✔ 1️⃣ 防止接口“坏掉”
比如:

  • 参数变了
  • 返回字段改了
  • HTTP状态错了

✔ 2️⃣ 是后端最常用测试
很多公司:
👉 API测试 = 测试主力

✔ 3️⃣ 适合 CI/CD
可以在:

Git push → 自动跑API测试

API测试常见工具

  • Postman
  • RestAssured
  • JUnit
  • Spring MockMvc

❌ 误区:

“只要调用接口就是单元测试”

✔ 正确:

只要走 HTTP → 就是 API测试
不管有没有 mock

单元测试

单元测试(Unit Testing),本质是:

👉 对“最小代码单元”(函数 / 方法)进行验证,确保它逻辑正确

它是所有测试里最基础、最细粒度、最快的一层

👉 单元测试 = 测一个函数有没有写对

以你熟悉的评论系统为例:

CommentService.validateComment()

✔ 单元测试关注的是:
1️⃣ 业务规则是否正确

评论不能为空
评论不能超过 500 字
不能包含敏感词

2️⃣ 函数输出是否正确
输入:

"hello world"

输出:

true

3️⃣ 边界情况

空字符串
超长文本
null
特殊字符

以 Java 为例:

@Test
public void testValidateComment() {
    CommentService service = new CommentService();

    boolean result = service.validateComment("hello");

    assertTrue(result);
}

单元测试的核心特点
✔ 1️⃣ 最小粒度

一个方法 = 一个测试目标

✔ 2️⃣ 不依赖外部系统(关键)
通常:

  • ❌ 不连数据库
  • ❌ 不调 Redis
  • ❌ 不发 HTTP

👉 全部 mock

✔ 3️⃣ 运行速度极快

几毫秒级别

✔ 4️⃣ 可重复执行
👉 不依赖环境状态

单元测试 vs Mock(重点)
因为单元测试不允许依赖外部系统,所以会用:

  • Mockito
when(redis.get("key")).thenReturn("value");

👉 把 Redis “假装出来”

单元测试的作用
✔ 1️⃣ 防止逻辑写错
比如:

热度计算公式写错

✔ 2️⃣ 防止重构崩溃
改代码时:
👉 单元测试能快速发现问题

✔ 3️⃣ 提升代码质量
写单元测试 = 强制你拆分逻辑

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐