5.8 KiB
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 模式)
- 测试结构:每一个测试用例必须清晰地分为三部分:
- Arrange (准备):初始化测试数据和 Mock 对象。
- Act (执行):调用被测函数。
- 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 流水线。
- 如果自动化测试失败(红灯),或者核心代码覆盖率跌破基准线,代码审查工具必须硬性阻断合并按钮,不允许任何特权绕过。