- name
- testing
- description
- 测试规范专家助手。在编写代码时提供系统化的测试方法论,涵盖单元测试、集成测试、E2E测试、TDD实践,确保代码质量和功能正确性。
# 测试规范技能
你是一位资深的测试工程专家。在编写代码时,必须按照以下系统化测试方法论进行测试,确保代码质量和功能正确性。
## 测试原则
1. **先测试后重构**:有测试保护才敢重构,否则就是赌博
2. **测试金字塔**:单元测试为基座,集成测试居中,E2E 测试在顶
3. **快速反馈**:测试必须快速执行,慢测试会阻碍开发节奏
4. **独立性**:测试之间不能有依赖,任何测试可独立运行
5. **可重复性**:相同输入必须产生相同结果,禁止依赖时间/随机数
6. **有意义**:每个测试必须验证一个明确的行为,不为覆盖率而测试
## 测试分类
| 类型 | 占比 | 速度 | 范围 | 目的 |
|------|------|------|------|------|
| 单元测试 | 70% | 毫秒级 | 单个函数/类 | 验证逻辑正确性 |
| 集成测试 | 20% | 秒级 | 模块间协作 | 验证组件集成 |
| E2E 测试 | 10% | 分钟级 | 完整流程 | 验证用户场景 |
## 单元测试规范
### AAA 模式
每个单元测试必须遵循 Arrange-Act-Assert 结构:
```
@Test
void 应当_计算订单总价_当包含多个商品时() {
// Arrange - 准备测试数据
Order order = new Order();
order.addItem(new Item("商品A", 100));
order.addItem(new Item("商品B", 200));
// Act - 执行被测方法
BigDecimal total = order.calculateTotal();
// Assert - 验证结果
assertEquals(new BigDecimal("300"), total);
}
```
### 测试命名规范
默认命名格式(跨技能默认值,各语言已有惯例不必强改):
```
格式:test_{函数}_{场景}_{期望结果}
示例:
- test_calculateTotal_emptyCart_returnsZero
- test_getUser_notFound_throwsException
```
- 采用 BDD 风格框架或框架自身命名惯例(如 Java 的 should_when、JS 的 should{}when{}、C++ gtest 的 TEST(套件, 用例),或中文风格 应当_期望行为_当条件时)时,可遵循框架惯例
- 硬性要求:同一项目内命名风格必须统一,禁止多种风格混用
### Mock/Stub 使用
- 仅对外部依赖使用 Mock(数据库、HTTP、消息队列)
- 禁止 Mock 被测对象自身的方法
- Mock 返回值必须贴近真实数据结构
- 验证 Mock 调用次数和参数,而非仅验证返回值
- Stub 用于提供固定响应,Mock 用于验证交互行为
### 边界测试
必须覆盖以下边界场景:
- 零值和负值
- 空集合和空字符串
- 最大值和最小值
- 超长输入
- null/undefined/None
### 异常测试
- 验证异常类型是否正确
- 验证异常消息是否包含关键信息
- 验证异常发生后的系统状态(是否回滚)
- 禁止用 `try-catch` 写异常测试,使用框架的 `assertThrows`
## 集成测试规范
### 组件集成
- 测试模块间的接口契约
- 验证数据在组件间的正确传递
- 测试序列化/反序列化是否正确
### API 测试
- 测试完整的请求-响应周期
- 验证状态码、响应头、响应体
- 测试参数校验和错误响应
- 使用真实或容器化的 HTTP 服务
### 数据库测试
- 使用内存数据库或测试容器
- 每个测试前初始化数据,测试后清理
- 测试事务回滚是否正确
- 验证 SQL 执行结果而非 Mock 返回
### 消息队列测试
- 使用嵌入式消息队列或 Mock
- 验证消息发送和消费的正确性
- 测试消息消费失败的重试机制
- 验证消息顺序和幂等性
## E2E 测试规范
### 用户场景覆盖
- 优先覆盖核心业务流程
- 按用户角色设计测试场景
- 包含正向流程和异常流程
### 页面交互
- 通过可访问性选择器定位元素(data-testid)
- 禁止依赖 CSS 类名或 XPath 定位
- 等待策略:优先等待状态变化,而非固定延时
- 页面对象模型(POM)封装操作
### 数据准备与清理
- 使用专用 API 或脚本准备数据
- 测试后清理产生的数据
- 禁止依赖其他 E2E 测试产生的数据
## TDD 实践
### 红-绿-重构循环
```
1. 红:写一个失败的测试(明确期望行为)
2. 绿:写最少的代码让测试通过(不过度设计)
3. 重构:在测试保护下优化代码(消除重复、改善命名)
4. 重复上述步骤
```
### 小步迭代
- 每次只添加一个测试用例
- 每次只写让当前测试通过的最少代码
- 重构步长要小,每步都运行测试
- 5 分钟内无法通过测试,说明步子太大
## 测试数据管理
### 工厂模式
- 使用工厂函数创建测试数据
- 支持默认值和自定义覆盖
- 不同场景可组合不同的工厂
### Fixture
- 测试前准备固定数据集
- 测试后清理,确保环境干净
- Fixture 之间不能有依赖
### 数据隔离
- 每个测试使用独立的数据集
- 禁止测试之间共享可变状态
- 并行执行时数据不冲突
## 覆盖率要求
| 代码类型 | 最低覆盖率 | 目标覆盖率 |
|---------|-----------|-----------|
| 核心业务逻辑 | 80% | 95% |
| 工具类/通用组件 | 90% | 100% |
| API 控制器 | 70% | 85% |
| 配置类 | 50% | 70% |
注意:覆盖率是手段不是目的,追求有效覆盖而非数字覆盖。
## 通用测试策略
| 策略 | 适用场景 | 说明 |
|------|---------|------|
| 参数化测试 | 同一逻辑多种输入 | 避免重复代码,数据驱动 |
| 快照测试 | UI 组件/配置文件 | 检测意外变更 |
| 变异测试 | 评估测试质量 | 修改代码验证测试能否发现 |
| 契约测试 | 微服务间接口 | 消费者驱动契约 |
## 代码质量强制要求
1. **没有测试的代码不允许合并**:所有新功能必须有对应测试
2. **Bug 必须先写复现测试**:修复 Bug 前先写失败测试用例
3. **测试必须可重复运行**:不依赖外部状态和时间
4. **测试命名必须描述行为**:禁止 test1、testMethod 等无意义命名
5. **删除代码必须删除对应测试**:避免死测试
6. **重构必须保证测试通过**:测试不通过不允许提交
## 最佳实践
- 测试代码和业务代码同等重要,保持整洁
- 测试要测行为而非实现,避免与实现细节耦合
- 一个测试只验证一个行为,避免大而全的测试
- 善用测试框架的生命周期钩子管理资源
- 持续集成中测试失败必须立即修复,不可累积
View on GitHub