Files
nexus/Project/fonrey/TECH_STACK/测试规范.md
2026-04-30 20:33:51 +08:00

11 KiB
Raw Blame History

For AI assistants: Read this entire file before writing any test code. All decisions here are final. Do not suggest alternatives unless asked.

Fonrey 测试规范TEST_SPEC

版本: 1.2
项目: Fonrey 房产经纪管理系统
技术栈: Django 4.x + django-tenants + PostgreSQL 16 + Redis + Celery + HTMX + Playwright
关联文档: TECH_STACK/TECH_STACK.mdPRD/TASK.mdTEST_CASES/TEST_CASE_ID_SPEC.mdTEST_CASES/TEST_CASE_REGISTRY.md、各模块技术方案(登录/权限/房源/客源/楼盘/组织人事/系统管理)
最后更新: 2026-04-30


变更历史

日期 变更人 变更内容
2026-04-30 Atlas 补充“变更历史”章节(文档治理)

一、文档定位与边界

本文件定义项目统一测试标准:

  1. 测试分层与覆盖率目标
  2. 测试目录与夹具fixture约定
  3. 多租户与 HTMX 场景测试规范
  4. CI 执行基线与失败处理流程
  5. AI 辅助开发的“测试随功能交付”硬约束

本文件不替代模块级测试设计。每个业务模块的案例细节以对应技术方案和 PRD AC 为准。


二、测试目标与覆盖基线

Fonrey 采用 AI 驱动迭代,测试是质量兜底。所有 P0 User Story 必须做到“功能 + 测试”同步交付。

2.1 覆盖率目标

层级 最低目标
core/ 基础模块 ≥ 90%
apps/*/services/ 业务逻辑层 ≥ 80%
apps/*/views* 接口与视图层 ≥ 70%
apps/*/tasks.py 异步任务 ≥ 70%
E2E 核心测试用例 覆盖指定核心用例并全部通过

2.2 质量门禁

  • 每个 P0 US 对应至少一个集成测试场景集。
  • PR 合并前:单元 + 集成必须全绿。
  • main/develop:每日自动跑全量(含 E2E 核心测试用例)。

三、测试分层架构

┌─────────────────────────────────────────┐
│ E2E 测试(测试用例)                    │  ← Playwright
├─────────────────────────────────────────┤
│ 集成测试HTTP / View / Service / DB  │  ← pytest-django + TenantClient
├─────────────────────────────────────────┤
│ 单元测试(纯逻辑)                      │  ← pytest + factory_boy + mock
└─────────────────────────────────────────┘

3.1 单元测试

  • 目标:服务层、工具层、任务函数的逻辑正确性。
  • 约束:不启动真实 HTTP不依赖外部网络。

3.2 集成测试

  • 目标验证完整请求链路View → Service → DB
  • 约束:必须使用 TenantClient,禁止 Django 原生 Client()

3.3 E2E 测试

  • 目标:验证真实用户关键路径。
  • 约束:只覆盖核心测试用例,避免把所有细节都堆到 E2E。

四、工具选型与依赖

类型 工具 版本建议 用途
测试框架 pytest ≥ 8.x 统一运行器
Django 集成 pytest-django ≥ 4.x DB/Client/Settings
数据工厂 factory_boy ≥ 3.x 生成测试数据
假数据 Faker ≥ 25.x 中文业务数据
Mock pytest-mock ≥ 3.x 外部依赖打桩
HTTP Mock responses ≥ 0.25.x 三方 HTTP 隔离
覆盖率 pytest-cov ≥ 5.x coverage 报告
并行 pytest-xdist ≥ 3.x 加速单测/集成
E2E playwright + pytest-playwright ≥ 1.44 / ≥ 0.5 浏览器自动化

安装基线:

pip install -r requirements/test.txt
playwright install chromium

五、目录结构约定

tests/
├── conftest.py
├── settings_test.py
├── factories/
│   ├── tenant_factory.py
│   ├── account_factory.py
│   ├── permission_factory.py
│   ├── complex_factory.py
│   ├── property_factory.py
│   ├── client_factory.py
│   └── org_factory.py
├── unit/
│   ├── test_encryption.py
│   ├── test_soft_delete.py
│   ├── test_*_service.py
│   └── test_celery_tasks.py
├── integration/
│   ├── account/test_us_account.py
│   ├── permission/test_us_permission.py
│   ├── complex/test_us_complex.py
│   ├── property/test_us_property.py
│   ├── client/test_us_client.py
│   ├── org/test_us_org.py
│   └── setting/test_us_setting.py
└── e2e/
    ├── conftest.py
    ├── test_journey_login.py
    ├── test_journey_property.py
    ├── test_journey_client.py
    ├── test_journey_permission.py
    └── test_journey_onboarding.py

六、多租户测试约定(强制)

6.1 核心原则

  1. 所有 DB 测试在租户 schema 上下文执行。
  2. 业务数据禁止直接在 public schema 断言。
  3. 事务隔离默认开启,测试间不得共享可变状态。
  4. 测试请求必须经 TenantClient 发出。

6.2 标准 fixture最小集合

  • tenant
  • tenant_client
  • admin_user
  • staff_user
  • authenticated_client

6.3 禁止事项

  • 禁止手工 SET search_path
  • 禁止跨租户数据断言
  • 禁止在集成测试用 Django 原生 Client()

七、单元测试规范

7.1 覆盖范围

代码范围 示例文件
core/encryption.py tests/unit/test_encryption.py
core/models/base.py tests/unit/test_soft_delete.py
apps/*/services/ tests/unit/test_*_service.py
apps/*/tasks.py tests/unit/test_celery_tasks.py

7.2 Celery 测试模式

tests/settings_test.py 必须启用:

CELERY_TASK_ALWAYS_EAGER = True
CELERY_TASK_EAGER_PROPAGATES = True

并统一使用:

result = some_task.apply(args=[...])

7.3 PII 相关必测点

  • 密文不等于明文
  • 同明文重复加密产生不同密文(随机 nonce
  • 解密结果与原文一致
  • 哈希索引稳定(同明文同 hash

八、集成测试规范

8.1 请求模式

类型 Header 预期
普通页面请求 完整 HTML
HTMX 局刷请求 HTTP_HX_REQUEST=true HTML 片段

8.2 权限覆盖最小集

每个受保护接口必须覆盖:

  1. 有权限:200
  2. 无权限:403
  3. 未登录:302

8.3 User Story 映射基线

US 范围 测试文件
US-ACCOUNT-001~003 tests/integration/account/test_us_account.py
US-PERMISSION-001~005 tests/integration/permission/test_us_permission.py
US-COMPLEX-001~003 tests/integration/complex/test_us_complex.py
US-PROPERTY-001~008 tests/integration/property/test_us_property.py
US-CLIENT-001~017 tests/integration/client/test_us_client.py
US-ORG-001~003 tests/integration/org/test_us_org.py
US-SETTING-001 tests/integration/setting/test_us_setting.py

8.4 外部依赖 Mock 规范

  • R2mock boto3.client
  • Redisfakeredis / locmem cache
  • 邮件locmem backend
  • 第三方 HTTPresponses 全量拦截

九、E2E 测试规范

9.1 核心测试用例(必须)

  • E2E 覆盖对象采用“测试用例”定义不使用“旅程编号J-xx”。
  • 每条 E2E 用例必须绑定全局唯一测试用例IDTC-FON-XXXXXX
  • 当前登录模块核心用例以 TEST_CASES/TEST_CASES_LOGIN_MODULE.md 为准(TC-FON-000001 ~ TC-FON-000048)。
  • 其他模块(房源/客源/组织/权限等)按 TEST_CASES/TEST_CASE_REGISTRY.md 分配编号后补充。

9.2 Playwright 约束

  • 默认 Chromium
  • CI 使用 headless
  • 禁止 wait_for_timeout() 固定等待
  • 优先语义等待:wait_for_url / expect(locator) / networkidle

9.3 HTMX 页面注意事项

HTMX 更新后 URL 可不变,断言前必须等待请求完成:

page.click('button:has-text("筛选")')
page.wait_for_load_state('networkidle')

十、测试用例编号与注册规范(强制)

10.1 编号规范

  • 测试用例IDTC-FON-XXXXXX(全局唯一)
  • 步骤IDTC-FON-XXXXXX-SYY
  • 详见:TEST_CASES/TEST_CASE_ID_SPEC.md

10.2 注册流程

  1. 新增用例前,先在 TEST_CASES/TEST_CASE_REGISTRY.md 查看下一个可用编号。
  2. 先登记编号段(可先 reserved),再编写文档和代码。
  3. 合并前状态改为 active,并更新“当前编号水位”。

10.3 强约束

  • 不允许按模块重置编号。
  • 不允许复用已废弃编号。
  • 不允许未登记编号直接入库测试代码。

十一、测试配置基线

11.1 pytest.ini

[pytest]
DJANGO_SETTINGS_MODULE = tests.settings_test
python_files = test_*.py
addopts = --tb=short --strict-markers -q
markers =
    unit
    integration
    e2e
    slow

11.2 tests/settings_test.py 关键项

  • Celery eager 模式开启
  • Cache 使用测试后端locmem/fakeredis
  • 邮件使用 locmem backend
  • 媒体文件使用临时目录
  • DEBUG=False(贴近生产)

十二、CI 自动化运行

12.1 触发策略

  • 每日定时全量测试
  • main/develop 每次 push 触发

12.2 流水线拆分

  1. unit-and-integration
  2. e2e(依赖前者成功后执行)

12.3 最低产物

  • 覆盖率报告(终端 + 平台上传)
  • E2E 失败截图 artifact
  • 测试结果明细(至少含 run_idtest_case_idstep_idstatuserror_messageexpected_resultactual_result

十三、AI 协作测试要求

每个 User Story 实现后,必须同时补齐:

  • Factory如缺失
  • Service 单元测试(正常 + 至少2个边界
  • View/API 集成测试(覆盖全部 AC
  • 权限三态与 HTMX/普通请求双形态

修复顺序:

  1. 先修功能代码
  2. 仅当测试确实错误才改测试
  3. 本地复跑通过后再提交

十四、禁止项Do NOT

  • 禁止 Django 原生 Client() 进行租户集成测试
  • 禁止固定等待(sleep / wait_for_timeout
  • 禁止真实调用外部服务
  • 禁止测试之间共享可变数据
  • 禁止无权限/未登录场景缺失
  • 禁止空测试占位后不补全
  • 禁止未分配 TC-FON-XXXXXX 的匿名测试入库

十五、文档同步规则

  • 新增/调整 User Story同步 PRD/TASK.md 与集成测试映射
  • 模块 API 变更:同步对应模块技术方案
  • 测试目录变更:同步本文件目录结构与 CI 脚本
  • 新增测试基建fixture/工具):同步 AGENTS.md 与本文件
  • 新增测试用例:同步 TEST_CASES/TEST_CASE_REGISTRY.md(编号段、水位、状态)