Files
cps-develop-docs/04 - Quality & Review/4.1 自动化测试规范.md

6.0 KiB
Raw Blame History

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 流水线。
    • 如果自动化测试失败(红灯),或者核心代码覆盖率跌破基准线,代码审查工具必须硬性阻断合并按钮,不允许任何特权绕过。

🤖 [附加] AI 助手执行协议 (AI Output Schema)

绝对红线:强制使用 pytest 框架;测试用例内部必须使用注释显式划分为 # Arrange, # Act, # Assert 三个标准区块。