77 lines
5.8 KiB
Markdown
77 lines
5.8 KiB
Markdown
|
|
# **4.1 自动化测试规范**
|
|||
|
|
|
|||
|
|
自动化测试是保障系统重构信心、防止线上代码回归(Regression)的唯一有效手段。本规范旨在指导研发团队编写**高优、稳定、可维护**的测试代码,坚决抵制“为了追求覆盖率而写无意义断言”的形式主义。
|
|||
|
|
|
|||
|
|
### **4.1.1 测试分层策略 (Testing Pyramid)**
|
|||
|
|
|
|||
|
|
团队的自动化测试必须遵循经典的“测试金字塔”原则,明确不同测试的边界与职责:
|
|||
|
|
|
|||
|
|
* **单元测试 (Unit Tests \- 占比 70%)**:运行极快,完全隔离。仅测试单一函数/方法的内部逻辑。**绝对禁止**任何真实的网络 I/O 和数据库连接。
|
|||
|
|
* **集成测试 (Integration Tests \- 占比 20%)**:验证多个内部组件能否协同工作。**允许**连接真实的测试数据库或本地 Redis,但**禁止**调用外部第三方系统(如真实的支付网关或微信 API)。
|
|||
|
|
* **接口/端到端自动化测试 (API/E2E Tests \- 占比 10%)**:从用户视角出发,把整个系统当做黑盒,通过 HTTP 协议发起真实请求,验证最终的 Response 和副作用。
|
|||
|
|
|
|||
|
|
### **4.1.2 单元测试编写规范与覆盖率要求**
|
|||
|
|
|
|||
|
|
**核心原则:Arrange \- Act \- Assert (3A 模式)**
|
|||
|
|
|
|||
|
|
* **测试结构**:每一个测试用例必须清晰地分为三部分:
|
|||
|
|
1. Arrange (准备):初始化测试数据和 Mock 对象。
|
|||
|
|
2. Act (执行):调用被测函数。
|
|||
|
|
3. Assert (断言):验证返回值或内部方法调用的状态。
|
|||
|
|
* **命名规范**:测试函数名必须能清晰表达测试意图。格式推荐:test\_\<被测方法\>\_\<测试场景\>\_\<预期结果\>。
|
|||
|
|
* *✅ 正确示例:test\_calculate\_discount\_with\_vip\_user\_returns\_half\_price()*
|
|||
|
|
* **覆盖率要求 (不搞一刀切)**:
|
|||
|
|
* **核心业务领域层 (Domain/Service)**:核心算法、金额计算、状态流转的单元测试行覆盖率**必须 \>= 80%**。
|
|||
|
|
* **边缘或纯框架粘合层 (Controller/View)**:不做硬性单元测试覆盖率要求,应交由“接口自动化测试”来覆盖。
|
|||
|
|
* *红线:严禁为了凑覆盖率去测试框架自带的 Getter/Setter 或基础的 ORM 查询。*
|
|||
|
|
|
|||
|
|
### **4.1.3 Mock 数据与测试对象构造原则**
|
|||
|
|
|
|||
|
|
脆弱的测试往往来源于糟糕的测试数据构造方式。
|
|||
|
|
|
|||
|
|
* **坚决弃用手动组装大字典**:严禁在测试代码中写几百行的字典或 JSON 来伪造数据库对象。这会导致测试代码极难维护。
|
|||
|
|
* **引入工厂模式 (Factory)**:强制使用 factory\_boy (Python) 或类似工具(如 Java 的 DataFaker)来生成测试对象实体。
|
|||
|
|
\# ✅ 正确示范:使用 Factory 快速生成具有合法默认值的测试对象
|
|||
|
|
user \= UserFactory(role='admin', is\_active=True)
|
|||
|
|
order \= OrderFactory(user=user, amount=100)
|
|||
|
|
|
|||
|
|
* **公共数据复用 (Fixtures)**:跨测试用例复用的基础数据(如登录凭证、基础配置),必须统一定义在 conftest.py(针对 Pytest 框架)中,通过依赖注入提供给测试用例。
|
|||
|
|
* **Mock 的外部边界红线**:
|
|||
|
|
* **必须 Mock**:所有跨出当前服务进程的调用(如请求 AWS、阿里云、第三方大模型、其它微服务)在单测和集成测试中**必须被拦截并 Mock**。
|
|||
|
|
* **禁止滥用 Mock**:不要在集成测试中去 Mock 系统内部的私有方法。Mock 应该发生在系统边界处。
|
|||
|
|
|
|||
|
|
### **4.1.4 集成测试规范 (Integration Testing)**
|
|||
|
|
|
|||
|
|
集成测试的核心目的是验证系统组件与外部基础设施(特别是数据库)的交互是否正确。
|
|||
|
|
|
|||
|
|
* **数据库环境清理 (极其重要)**:
|
|||
|
|
* 集成测试必须连接到独立的测试数据库(如本地内存 DB,或由 CI 动态拉起的 Docker DB)。
|
|||
|
|
* **红线:严禁测试用例之间产生数据污染。** 每个测试用例执行完毕后,必须**触发事务回滚 (Transaction Rollback)** 或清空相关表。在 Django/pytest 体系中,强制使用 @pytest.mark.django\_db 确保测试在事务中运行。
|
|||
|
|
* **验证副作用**:集成测试不仅要验证函数的 return 值,更要验证数据库的真实副作用(Side Effects)。
|
|||
|
|
def test\_cancel\_order\_updates\_db\_status():
|
|||
|
|
order \= OrderFactory(status='PENDING')
|
|||
|
|
|
|||
|
|
\# Act
|
|||
|
|
cancel\_order\_service(order.id)
|
|||
|
|
|
|||
|
|
\# Assert:必须重新从真实数据库查出数据,验证更新是否落盘
|
|||
|
|
order.refresh\_from\_db()
|
|||
|
|
assert order.status \== 'CANCELLED'
|
|||
|
|
|
|||
|
|
### **4.1.5 接口自动化测试要求 (API Testing)**
|
|||
|
|
|
|||
|
|
接口自动化测试用于替代绝大部分的“手动 Postman 联调”,它是持续交付 (CI/CD) 的最后一道质量门禁。
|
|||
|
|
|
|||
|
|
* **黑盒视角**:测试代码不需要知道内部是怎么实现的。仅通过框架的 APIClient 或 HTTP 客户端(如 httpx, RestAssured)发起请求。
|
|||
|
|
* **全链路验证**:不要仅仅测试单一接口的连通性,必须测试**核心业务链路 (Happy Path)**。
|
|||
|
|
* *示例场景:* 1\. 调用登录接口获取 Token \-\> 2\. 携带 Token 创建订单 \-\> 3\. 调用查询接口断言订单存在 \-\> 4\. 调用取消接口 \-\> 5\. 再次查询断言状态变更。
|
|||
|
|
* **契约断言 (Contract Assertion)**:
|
|||
|
|
* 必须断言 HTTP 状态码(如 200, 201, 400, 403)。
|
|||
|
|
* 必须断言外层统一响应结构(code, message)。
|
|||
|
|
* 必须断言核心业务数据字段的存在与类型,确保 API 向前兼容。
|
|||
|
|
|
|||
|
|
### **4.1.6 质量门禁与 CI/CD 强制执行**
|
|||
|
|
|
|||
|
|
* **本地提交前拦截**:推荐使用 Git pre-commit 钩子,在本地 Commit 前执行快速的单元测试。
|
|||
|
|
* **CI 自动化阻断**:任何合并到主干分支(如 main, develop)的 Pull Request/Merge Request,必须触发 CI 流水线。
|
|||
|
|
* 如果自动化测试失败(红灯),或者核心代码覆盖率跌破基准线,代码审查工具必须**硬性阻断**合并按钮,不允许任何特权绕过。
|