11 KiB
11 KiB
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.md、PRD/TASK.md、TEST_CASES/TEST_CASE_ID_SPEC.md、TEST_CASES/TEST_CASE_REGISTRY.md、各模块技术方案(登录/权限/房源/客源/楼盘/组织人事/系统管理)
最后更新: 2026-04-30
变更历史
| 日期 | 变更人 | 变更内容 |
|---|---|---|
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
一、文档定位与边界
本文件定义项目统一测试标准:
- 测试分层与覆盖率目标
- 测试目录与夹具(fixture)约定
- 多租户与 HTMX 场景测试规范
- CI 执行基线与失败处理流程
- 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 核心原则
- 所有 DB 测试在租户 schema 上下文执行。
- 业务数据禁止直接在
publicschema 断言。 - 事务隔离默认开启,测试间不得共享可变状态。
- 测试请求必须经
TenantClient发出。
6.2 标准 fixture(最小集合)
tenanttenant_clientadmin_userstaff_userauthenticated_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 权限覆盖最小集
每个受保护接口必须覆盖:
- 有权限:
200 - 无权限:
403 - 未登录:
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 规范
- R2:mock
boto3.client - Redis:fakeredis / locmem cache
- 邮件:locmem backend
- 第三方 HTTP:
responses全量拦截
九、E2E 测试规范
9.1 核心测试用例(必须)
- E2E 覆盖对象采用“测试用例”定义,不使用“旅程编号(J-xx)”。
- 每条 E2E 用例必须绑定全局唯一测试用例ID:
TC-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 编号规范
- 测试用例ID:
TC-FON-XXXXXX(全局唯一) - 步骤ID:
TC-FON-XXXXXX-SYY - 详见:
TEST_CASES/TEST_CASE_ID_SPEC.md
10.2 注册流程
- 新增用例前,先在
TEST_CASES/TEST_CASE_REGISTRY.md查看下一个可用编号。 - 先登记编号段(可先
reserved),再编写文档和代码。 - 合并前状态改为
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 流水线拆分
unit-and-integratione2e(依赖前者成功后执行)
12.3 最低产物
- 覆盖率报告(终端 + 平台上传)
- E2E 失败截图 artifact
- 测试结果明细(至少含
run_id、test_case_id、step_id、status、error_message、expected_result、actual_result)
十三、AI 协作测试要求
每个 User Story 实现后,必须同时补齐:
- Factory(如缺失)
- Service 单元测试(正常 + 至少2个边界)
- View/API 集成测试(覆盖全部 AC)
- 权限三态与 HTMX/普通请求双形态
修复顺序:
- 先修功能代码
- 仅当测试确实错误才改测试
- 本地复跑通过后再提交
十四、禁止项(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(编号段、水位、状态)