first commit
This commit is contained in:
@@ -0,0 +1,454 @@
|
||||
# 自动测试说明
|
||||
|
||||
## 1. 目标
|
||||
|
||||
这套测试只做一件事:
|
||||
|
||||
- 用固定配置初始化测试环境;
|
||||
- 一键运行测试;
|
||||
- 验证同步系统能不能完成一轮正常同步;
|
||||
- 验证常见的更新接口能不能工作;
|
||||
- 能把问题大致分成三类:数据问题、推送系统问题、后端接口问题。
|
||||
|
||||
不追求把所有情况都测完,也不追求覆盖所有脏数据。测试深度控制在:
|
||||
|
||||
- 能跑通一次正常流程;
|
||||
- 能验证一批关键 update;
|
||||
- 能处理一些基本异常;
|
||||
- 每轮都能留下清楚的报告,供下一轮继续改。
|
||||
|
||||
## 2. 测试系统的组成
|
||||
|
||||
测试系统由 4 部分组成:
|
||||
|
||||
1. **测试配置**
|
||||
2. **初始化脚本**
|
||||
3. **按 domain 拆分的用例**
|
||||
4. **统一运行脚本**
|
||||
|
||||
只要把这 4 部分准备好,后面就应该做到:**运行一个脚本,就自动完成初始化、执行、分析、出报告。**
|
||||
|
||||
### 当前已落地的文件
|
||||
|
||||
目前已经先实现了一版最小骨架:
|
||||
|
||||
- 测试总配置:[tests/fixtures/auto_sync/auto_test_config.yaml](tests/fixtures/auto_sync/auto_test_config.yaml)
|
||||
- 流水线测试配置:[run_profiles/jsonl_to_api.test.yaml](run_profiles/jsonl_to_api.test.yaml)
|
||||
- 初始化脚本:[scripts/auto_test_init.py](scripts/auto_test_init.py)
|
||||
- 统一运行脚本:[scripts/run_auto_test.py](scripts/run_auto_test.py)
|
||||
- 公共工具:[scripts/auto_test_lib.py](scripts/auto_test_lib.py)
|
||||
- 第一个 domain 用例:[tests/fixtures/auto_sync/domains/contract.yaml](tests/fixtures/auto_sync/domains/contract.yaml)
|
||||
|
||||
## 3. 配置管理
|
||||
|
||||
测试环境必须基于配置初始化,不能靠手工改路径。
|
||||
|
||||
配置里至少要能定义这些内容:
|
||||
|
||||
- 后端代码目录;
|
||||
- 后端启动命令;
|
||||
- 后端恢复数据库命令;
|
||||
- 测试使用的数据库名;
|
||||
- CouchDB 连接信息;
|
||||
- 本地同步状态数据库路径;
|
||||
- 基础种子数据目录;
|
||||
- 同步测试数据目录;
|
||||
- 临时测试数据目录;
|
||||
- 同步系统运行配置文件路径。
|
||||
|
||||
建议单独准备一个测试配置,例如:
|
||||
|
||||
- `run_profiles/jsonl_to_api.test.yaml`
|
||||
- `docs/auto_test_spec` 中再约定测试总配置文件
|
||||
|
||||
### 数据目录分工
|
||||
|
||||
测试里至少有 3 类数据目录:
|
||||
|
||||
1. **基础种子数据**
|
||||
- 用来恢复后端里那些不能通过同步创建的数据。
|
||||
- 例如:`company`、`project`、`design_doc`。
|
||||
- 这类数据先进入后端数据库,给后续同步提供依赖。
|
||||
|
||||
2. **同步测试数据**
|
||||
- 用来测试可创建、可更新的业务数据。
|
||||
- 例如合同、结算、施工任务等。
|
||||
|
||||
3. **临时运行目录**
|
||||
- 每次测试前,把测试数据复制到这里。
|
||||
- 后续每一轮如果要改数据,也只改这里,不改原始测试集。
|
||||
|
||||
## 4. 初始化方式
|
||||
|
||||
初始化必须自动完成,不能再靠手工执行几条命令。
|
||||
|
||||
目标流程如下:
|
||||
|
||||
1. 读取测试配置;
|
||||
2. 如有旧测试数据库,先自动删除;
|
||||
3. 自动删除本地同步状态数据库;
|
||||
4. 自动执行后端的数据库恢复命令,导入基础种子数据;
|
||||
5. 自动启动后端;
|
||||
6. 自动等待后端 ready;
|
||||
7. 自动准备临时测试目录;
|
||||
8. 开始跑测试。
|
||||
|
||||
### 运行后的要求
|
||||
|
||||
- **测试跑完以后,数据库保留**,方便查看结果;
|
||||
- **下次再运行时,再自动清空旧库并重建**;
|
||||
- 不要求每次结束自动销毁环境。
|
||||
|
||||
## 5. 运行方式
|
||||
|
||||
不强制使用 `pytest`。
|
||||
|
||||
当前更适合的方式是:
|
||||
|
||||
- 用一个主脚本统一运行全部流程;
|
||||
- domain 用例由脚本按顺序调度;
|
||||
- 每个 domain 可以包含多轮 pipeline;
|
||||
- 每轮的输入数据和检查点都由脚本控制。
|
||||
|
||||
也就是:
|
||||
|
||||
- `测试配置 + 初始化脚本 + 分 domain 的用例 + 一个完整运行脚本`
|
||||
|
||||
## 6. 测试轮次
|
||||
|
||||
一次完整测试,允许分成多轮 pipeline。
|
||||
|
||||
典型做法:
|
||||
|
||||
### 第 1 轮:初始化后首次同步
|
||||
|
||||
目的:
|
||||
|
||||
- 验证基础依赖准备正确;
|
||||
- 验证 create 流程能跑通;
|
||||
- 验证绑定关系是否正常。
|
||||
|
||||
### 第 2 轮:在临时目录修改部分数据后再次同步
|
||||
|
||||
目的:
|
||||
|
||||
- 验证 update 接口;
|
||||
- 验证哪些数据应该更新;
|
||||
- 验证哪些数据应该保持不动。
|
||||
|
||||
### 第 3 轮:补充少量基本异常场景
|
||||
|
||||
目的:
|
||||
|
||||
- 验证系统遇到常见错误时能不能给出清楚结果;
|
||||
- 验证错误是否能定位到数据、推送系统或后端。
|
||||
|
||||
不要求无限轮次,也不要求复杂压力测试。
|
||||
|
||||
## 7. Domain 用例怎么设计
|
||||
|
||||
每个 domain 单独设计用例,例如:
|
||||
|
||||
- `company`
|
||||
- `project`
|
||||
- `contract`
|
||||
- `supplier`
|
||||
- `construction_task`
|
||||
- `contract_settlement`
|
||||
|
||||
但不是所有 domain 都从创建开始测。
|
||||
|
||||
要根据业务真实情况决定:
|
||||
|
||||
- 哪些 domain 只能作为基础种子存在;
|
||||
- 哪些 domain 可以通过同步创建;
|
||||
- 哪些 domain 要重点测 update。
|
||||
|
||||
### Domain 用例必须写清楚的内容
|
||||
|
||||
每个 domain 的用例说明都要先写文字,再写代码。文字说明必须经过你审定。
|
||||
|
||||
每组用例至少写清楚:
|
||||
|
||||
1. 这个 domain 的前置依赖是什么;
|
||||
2. 这个 domain 本轮准备哪些测试数据;
|
||||
3. 第几轮会创建哪些记录;
|
||||
4. 第几轮会修改哪些字段;
|
||||
5. 预期通过什么方式判断结果;
|
||||
6. 这个用例主要想识别哪类问题。
|
||||
|
||||
## 8. Domain 用例的测试原则
|
||||
|
||||
### 原则 1:优先覆盖大部分接口
|
||||
|
||||
目标不是追求完美覆盖,而是尽量覆盖大部分 create / update 接口,尤其是 update。
|
||||
|
||||
### 原则 2:只测明确的业务关系
|
||||
|
||||
用例里的依赖关系必须有文字说明,不能边跑边猜。
|
||||
|
||||
### 原则 3:可以通过改数据来构造用例
|
||||
|
||||
允许通过修改临时目录里的数据来构造 update 场景。
|
||||
|
||||
### 原则 4:判断结果不能只看日志
|
||||
|
||||
要结合下面几类证据一起判断:
|
||||
|
||||
- 日志;
|
||||
- collection 中的数据;
|
||||
- 持久化数据库中的结果;
|
||||
- 绑定记录;
|
||||
- 同步状态数据库。
|
||||
|
||||
### 原则 5:用例要能分出问题归属
|
||||
|
||||
每个用例都应该尽量帮助判断问题属于:
|
||||
|
||||
- 测试数据问题;
|
||||
- 推送系统问题;
|
||||
- 后端接口逻辑问题。
|
||||
|
||||
## 9. 建议的用例层次
|
||||
|
||||
每个 domain 的用例,优先按下面 4 类来补:
|
||||
|
||||
1. **正常创建**
|
||||
2. **正常更新**
|
||||
3. **关键绑定关系检查**
|
||||
4. **基本异常检查**
|
||||
|
||||
这里的“基本异常”只做常见的、对当前系统最有价值的,例如:
|
||||
|
||||
- 缺少依赖;
|
||||
- 关键字段不合法;
|
||||
- 远端返回明确错误;
|
||||
- 本地状态和远端状态不一致。
|
||||
|
||||
## 10. 运行脚本应该负责什么
|
||||
|
||||
统一运行脚本应负责:
|
||||
|
||||
1. 读取测试配置;
|
||||
2. 清空旧测试环境;
|
||||
3. 初始化后端数据库;
|
||||
4. 启动后端并等待可用;
|
||||
5. 准备临时测试数据;
|
||||
6. 按 domain 顺序执行各轮用例;
|
||||
7. 每轮运行 pipeline;
|
||||
8. 收集结果;
|
||||
9. 输出报告。
|
||||
|
||||
## 11. 测试报告要求
|
||||
|
||||
每轮都要有清晰报告,给下一轮继续优化使用。
|
||||
|
||||
报告至少包含:
|
||||
|
||||
- 测试时间;
|
||||
- 使用的配置;
|
||||
- 运行了哪些 domain;
|
||||
- 每个 domain 跑了几轮;
|
||||
- 每轮改了哪些数据;
|
||||
- 每轮成功 / 失败统计;
|
||||
- 失败样本;
|
||||
- 问题分类:数据 / 推送系统 / 后端;
|
||||
- 下一轮建议。
|
||||
|
||||
## 12. 当前结论
|
||||
|
||||
当前最合适的方案不是全量自动化,也不是一次性测完所有东西。
|
||||
|
||||
而是:
|
||||
|
||||
- 先做一套固定配置的测试环境;
|
||||
- 用一个脚本跑完整个流程;
|
||||
- 从少量 but 关键的 domain 开始;
|
||||
- 每个 domain 先把 create 和主要 update 跑通;
|
||||
- 每轮都留下明确报告;
|
||||
- 再逐步扩展。
|
||||
|
||||
这样更容易维护,也更适合后续让 Agent 按计划继续写代码。
|
||||
|
||||
## 13. 当前执行计划(2026-03-07)
|
||||
|
||||
当前轮次先处理两类目标:
|
||||
|
||||
1. `project_detail_data`
|
||||
- 继续确认可按统一 `project_detail_data` 语义验证的 key 与相关 update 接口在测试报告中可见、可追踪;
|
||||
- 重点检查它与后续 project 级 domain 连跑时是否污染状态。
|
||||
- 当前水电项目下,`production` 先不混入这组统一回归:后端已确认该接口会直接更新 `project` 字段,但不保证创建/更新可轮询的 `project_detail_data.production` 记录;后续待业务确认后再单列测试方案。
|
||||
|
||||
2. 剩余 domain
|
||||
- 当前优先处理:`contract_settlement_detail`、`personnel`、`personnel_detail`
|
||||
- 已完成并保持回归:`preparation`、`production`、`contract`、`contract_settlement`、`construction_task`、`construction_task_detail`、`material`、`material_detail`
|
||||
- 之后再继续:`units`、`contract_change`、`lar`、`lar_change`
|
||||
|
||||
本轮执行顺序:
|
||||
|
||||
1. 先补齐文字测试计划;
|
||||
2. 再修改测试脚本与 `tests/` 下测试数据;
|
||||
3. 逐个 domain 跑通;
|
||||
4. 最后回到整套自动测试顺序验证全量可跑通。
|
||||
|
||||
### 本轮强约束
|
||||
|
||||
- **禁止修改 `schemas/` 下任何文件。**
|
||||
- 不允许为了让测试通过而绕过 schema 校验。
|
||||
- 如果问题根因是后端接口/后端返回/后端数据模型不一致,应直接在报告里暴露并记录,不擅自改 schema。
|
||||
- 只有在确认是后端错误并得到明确指示后,才讨论是否调整类型定义。
|
||||
|
||||
### 本轮排查重点
|
||||
|
||||
1. `project_detail_data` 单跑已基本可用,但要继续验证与 `preparation`、`production` 连跑时是否造成绑定或状态污染;
|
||||
2. `preparation`、`production` 当前更像是“整套顺序执行时失败、单独执行可通过”的问题,优先检查运行顺序、临时数据、持久化状态和绑定残留;
|
||||
3. 其余 domain 按“先单 domain 跑通,再放回全量顺序”推进;
|
||||
- 当前先按 `contract_settlement_detail -> personnel -> personnel_detail` 顺序落地;
|
||||
4. 每修完一个 domain,都要保证报告中能看出本轮覆盖内容、绑定结果、字段变化和失败归因。
|
||||
5. 对 `project_detail_data.production`,禁止再用“接口没报错就直接记成功”的短路逻辑掩盖真实语义;当前阶段直接绕过该 key 的统一回归,保留差异说明。
|
||||
|
||||
## 14. 大规模测试方法:按轮迭代,而不是一次堆上下文
|
||||
|
||||
大规模测试的目标不是“把所有失败细节一次讲完”,而是:
|
||||
|
||||
- 每一轮只有一个清晰基线;
|
||||
- 每一轮只记录少量必须保留的信息;
|
||||
- 每一轮都能看到总计变化;
|
||||
- 每一轮都能区分“新问题、已修复问题、遗留问题”。
|
||||
|
||||
当前推荐固定采用 **单 domain 验证 + 全量聚合回归** 的两层节奏。
|
||||
|
||||
### 14.1 固定节奏
|
||||
|
||||
每一轮都按下面顺序执行:
|
||||
|
||||
1. **选定本轮目标**
|
||||
- 只选 1 个主问题,或者 1 组同类问题。
|
||||
- 例如:
|
||||
- 一个 domain 的 update 接口失败;
|
||||
- 一组共享 helper 导致的脚本设计问题;
|
||||
- 一类后端读写不一致问题。
|
||||
|
||||
2. **先单 domain 复现**
|
||||
- 用 [scripts/run_auto_test.py](scripts/run_auto_test.py) 只跑目标 domain。
|
||||
- 目的不是求“全绿”,而是先确认问题是否稳定复现。
|
||||
|
||||
3. **定位并修复一类根因**
|
||||
- 如果是测试脚本问题,就只修脚本;
|
||||
- 如果是后端问题,就在报告里明确标注为后端;
|
||||
- 如果是数据问题,就保留失败,不用 fallback 掩盖。
|
||||
|
||||
4. **回跑目标 domain**
|
||||
- 只看本 domain 是否改善;
|
||||
- 记录这轮减少了多少失败 case。
|
||||
|
||||
5. **再跑聚合回归**
|
||||
- 用 [scripts/run_auto_test_all_domains.py](scripts/run_auto_test_all_domains.py) 执行全量聚合;
|
||||
- 当前聚合模式是“**每个 domain 独立初始化并单独执行**”,用于避免跨 domain 状态污染。
|
||||
|
||||
6. **输出轮次结论**
|
||||
- 只保留:
|
||||
- 总 case 数;
|
||||
- 通过 / 失败数;
|
||||
- 新增失败;
|
||||
- 已修复失败;
|
||||
- 遗留失败;
|
||||
- 每个遗留失败的归因分类。
|
||||
|
||||
### 14.2 每轮只保留 4 份信息
|
||||
|
||||
为了避免上下文失控,每轮总结时只保留下面 4 份信息:
|
||||
|
||||
1. **总计快照**
|
||||
- `total_domains`
|
||||
- `passed_domains`
|
||||
- `failed_domains`
|
||||
- `total_cases`
|
||||
- `passed_cases`
|
||||
- `failed_cases`
|
||||
|
||||
2. **变化清单**
|
||||
- 本轮修复了哪些 case;
|
||||
- 本轮新增了哪些 case;
|
||||
- 哪些 case 没变化。
|
||||
|
||||
3. **失败分类表**
|
||||
- `script_design`:脚本设计 / 运行配置 / 断言策略问题;
|
||||
- `push_system`:状态机、绑定、依赖、持久化、推送链路问题;
|
||||
- `backend`:后端接口、后端读写模型、后端返回值问题;
|
||||
- `data`:测试数据不满足前置条件或数据本身不合法;
|
||||
- `flaky`:暂时只在聚合中出现、单跑不能稳定复现的问题。
|
||||
|
||||
4. **下一轮唯一目标**
|
||||
- 下一轮最多列 1~3 个目标;
|
||||
- 不把所有猜测都带到下一轮。
|
||||
|
||||
### 14.3 轮次汇总格式
|
||||
|
||||
每轮报告建议固定成下面的结构:
|
||||
|
||||
1. **Round N 总计**
|
||||
2. **与 Round N-1 对比**
|
||||
3. **本轮修复**
|
||||
4. **本轮新增**
|
||||
5. **遗留问题分类**
|
||||
6. **下一轮目标**
|
||||
|
||||
建议直接从聚合报告的 `summary.json` 中抽取总计,避免手工整理时带入过多细节。
|
||||
|
||||
### 14.4 建议的对比口径
|
||||
|
||||
比较两轮结果时,统一只按 `domain::round_name` 比较,不按日志文本比较。
|
||||
|
||||
也就是把每个 case 视为一个稳定键,例如:
|
||||
|
||||
- `project::round_2_base_info_update`
|
||||
- `project::round_3_investment_update`
|
||||
- `material_detail::round_2_update`
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
- 总数稳定;
|
||||
- 对比简单;
|
||||
- 很容易看出某个 case 是“由失败转通过”,还是“仍然失败”。
|
||||
|
||||
### 14.5 建议的推进策略
|
||||
|
||||
对于 10+ domain、数十个 case 的回归,建议始终按下面方式推进:
|
||||
|
||||
1. **先消灭稳定复现的单点失败**
|
||||
- 先修能稳定复现的问题,不先追偶发问题。
|
||||
|
||||
2. **再处理共享根因**
|
||||
- 如果多个 domain 共用同一个 helper、同一个运行配置、同一种绑定策略,优先处理这一层。
|
||||
|
||||
3. **最后单列 flaky**
|
||||
- 聚合里偶发失败、单跑通过的问题,不直接混入主结论;
|
||||
- 先标成 `flaky`,待重复出现后再升级处理。
|
||||
|
||||
### 14.6 当前这套系统中的实际判定方法
|
||||
|
||||
当前推荐把问题按下面顺序判定:
|
||||
|
||||
1. **先看单 domain 是否稳定失败**
|
||||
- 如果单跑失败,优先查该 domain 自身脚本、数据、后端接口。
|
||||
|
||||
2. **再看聚合回归是否额外引入失败**
|
||||
- 如果单跑通过、聚合失败,优先怀疑:
|
||||
- 运行顺序;
|
||||
- 环境残留;
|
||||
- 报告聚合方式;
|
||||
- 偶发后端错误。
|
||||
|
||||
3. **最后看后端是否写了但读不出来**
|
||||
- 如果 update 接口已命中,但回读字段缺失或不一致,要明确归类为 `backend`,而不是继续修改测试脚本绕过。
|
||||
|
||||
### 14.7 本文档要求的轮次目标
|
||||
|
||||
每一轮结束后,必须能一句话回答下面 3 个问题:
|
||||
|
||||
1. **总计有没有变好?**
|
||||
2. **变好是因为修了脚本、推送系统,还是确认了后端问题?**
|
||||
3. **下一轮只追哪一个主问题?**
|
||||
|
||||
如果一轮总结不能回答这 3 个问题,就说明这轮上下文保留得太多、结论还不够收敛。
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
large_scale_test:
|
||||
config_path: tests/fixtures/auto_sync/auto_test_config.yaml
|
||||
output_dir: test_results/auto_test/large_scale
|
||||
fail_on_failed_cases: false
|
||||
default_runner: aggregate
|
||||
default_init_mode: fresh
|
||||
classification:
|
||||
project::round_3_investment_update: backend
|
||||
material_detail::round_2_update: flaky
|
||||
rounds:
|
||||
- id: round_01_full_baseline
|
||||
title: 全量隔离基线
|
||||
enabled: true
|
||||
runner: aggregate
|
||||
init_mode: fresh
|
||||
objective: 建立当前 19 个 domain 的隔离回归基线,并确认遗留失败的分类。
|
||||
focus:
|
||||
- 全量聚合仍使用每个 domain 独立初始化,避免跨 domain 状态污染。
|
||||
- 先确认 project 与 material_detail 的当前状态,不在本轮混入额外修复动作。
|
||||
next_goal: 在保持全量基线的前提下,单独复核 project 与 material_detail,区分后端遗留问题和聚合偶发问题。
|
||||
- id: round_02_project_recheck
|
||||
title: project 后端复核
|
||||
enabled: true
|
||||
runner: domains
|
||||
init_mode: fresh
|
||||
domains:
|
||||
- project
|
||||
objective: 单独复核 project,确认 round_2 已修复,round_3 仅剩后端读回字段缺失。
|
||||
focus:
|
||||
- 只跑 project,避免无关上下文。
|
||||
- 明确区分脚本问题与后端问题。
|
||||
classification:
|
||||
project::round_3_investment_update: backend
|
||||
next_goal: 保留脚本侧修复结论,把 project round_3 作为后端待修项持续跟踪。
|
||||
- id: round_03_material_detail_recheck
|
||||
title: material_detail 波动复核
|
||||
enabled: true
|
||||
runner: domains
|
||||
init_mode: fresh
|
||||
domains:
|
||||
- material_detail
|
||||
objective: 单独复核 material_detail,确认聚合中的 round_2 失败是否只是偶发。
|
||||
focus:
|
||||
- 只跑 material_detail。
|
||||
- 如果单跑通过,就把聚合中的失败归为 flaky,不扩大处理范围。
|
||||
classification:
|
||||
material_detail::round_2_update: flaky
|
||||
next_goal: 若后续聚合再次出现同类失败,再升级为可复现问题处理。
|
||||
---
|
||||
# 大规模测试控制文档
|
||||
|
||||
这个文档同时承担两件事:
|
||||
|
||||
1. **控制大规模测试怎么跑**
|
||||
2. **记录每轮测试的目标、结果和改进过程**
|
||||
|
||||
## 使用方式
|
||||
|
||||
- 控制入口:调整本文档 frontmatter 中的 `rounds`
|
||||
- 执行脚本:[scripts/run_large_scale_auto_test.py](scripts/run_large_scale_auto_test.py)
|
||||
- 默认命令:`python scripts/run_large_scale_auto_test.py`
|
||||
|
||||
## 设计约束
|
||||
|
||||
- 默认使用 `fresh` 初始化,优先保证每轮从干净环境开始。
|
||||
- `aggregate` runner 适合大规模基线回归;它内部会对每个 domain 独立初始化。
|
||||
- `domains` runner 适合小范围复核;它会按 [scripts/run_auto_test.py](scripts/run_auto_test.py) 的语义执行。
|
||||
- 失败不应靠 fallback 掩盖;应在轮次记录里明确分类。
|
||||
|
||||
## Runner 约定
|
||||
|
||||
### `aggregate`
|
||||
|
||||
- 调用 [scripts/run_auto_test_all_domains.py](scripts/run_auto_test_all_domains.py)
|
||||
- 适合建立全量基线
|
||||
- 最能避免跨 domain 污染
|
||||
|
||||
### `domains`
|
||||
|
||||
- 调用 [scripts/run_auto_test.py](scripts/run_auto_test.py)
|
||||
- 适合复核单个或少量 domain
|
||||
- 用于缩小上下文,验证某个问题是否稳定复现
|
||||
|
||||
## Init 策略约定
|
||||
|
||||
### `fresh`
|
||||
|
||||
- 默认策略
|
||||
- 每轮都从新的初始化开始
|
||||
- 优先用于正式大规模测试
|
||||
|
||||
### `reuse`
|
||||
|
||||
- 透传 `--skip-init`
|
||||
- 只适合排查“连续执行是否污染状态”这一类问题
|
||||
- 不建议作为大规模基线默认值
|
||||
|
||||
### `clear-only`
|
||||
|
||||
- 只清空环境,不执行业务轮次
|
||||
- 用于单独校验清理逻辑
|
||||
|
||||
## 执行记录
|
||||
|
||||
下面这部分由脚本自动更新,不手工编辑。
|
||||
|
||||
<!-- LARGE_SCALE_RESULTS:START -->
|
||||
|
||||
## 最近一次执行 20260308-012707
|
||||
|
||||
- 控制文档: docs/auto_test_spec/large_scale_test_control.md
|
||||
- 执行轮次数: 1
|
||||
- 说明: 默认优先使用 fresh 初始化;若使用 aggregate runner,则每个 domain 仍会独立初始化。
|
||||
|
||||
### 轮次总览
|
||||
|
||||
| Round | 标题 | Runner | Init | Cases | Failed | 对比轮次 | 报告 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| round_01_full_baseline | 全量隔离基线 | aggregate | fresh | 42 | 1 | - | test_results/auto_test/reports/20260308-012707/report.md |
|
||||
|
||||
### round_01_full_baseline - 全量隔离基线
|
||||
|
||||
- 目标: 建立当前 19 个 domain 的隔离回归基线,并确认遗留失败的分类。
|
||||
- 运行方式: aggregate
|
||||
- 初始化策略: fresh
|
||||
- 执行命令: /Users/zyl/my_projects/ecm_sync_system/.venv/bin/python /Users/zyl/my_projects/ecm_sync_system/scripts/run_auto_test_all_domains.py --config tests/fixtures/auto_sync/auto_test_config.yaml
|
||||
- 单轮结果: 41 passed / 1 failed / 42 total cases
|
||||
- Domain 结果: 18 passed / 1 failed / 19 total domains
|
||||
- 原始报告: test_results/auto_test/reports/20260308-012707/report.md
|
||||
- 原始汇总: test_results/auto_test/reports/20260308-012707/summary.json
|
||||
- 本轮关注点:
|
||||
- 全量聚合仍使用每个 domain 独立初始化,避免跨 domain 状态污染。
|
||||
- 先确认 project 与 material_detail 的当前状态,不在本轮混入额外修复动作。
|
||||
- 对比轮次: 无可比较轮次
|
||||
- 可比较 case 数: 0
|
||||
- 对比结果: 本轮没有可比改进项,或与此前轮次无重叠 case。
|
||||
- 失败归因:
|
||||
- project::round_3_investment_update | backend | issues=1 | remote.project 字段校验失败: local=de4dc6d2-ea32-5c04-8430-83145d5d0765 target=f3e02e84-e81c-4aa6-88d4-f5aa108c8227; implementation_estimate: actual=None expected=1225000.0; static_total_investment: actual=None expected=1224300.0; completed_investment: actual=None expected=194500.0
|
||||
- 下一轮目标: 在保持全量基线的前提下,单独复核 project 与 material_detail,区分后端遗留问题和聚合偶发问题。
|
||||
- 脚本返回码: 1
|
||||
|
||||
<!-- LARGE_SCALE_RESULTS:END -->
|
||||
@@ -0,0 +1,42 @@
|
||||
# 差异字段汇总清单
|
||||
|
||||
本文档记录了在同步推流测试中,本地(Local payload)与远端(Remote API 响应/DB落库)产生明确差异的字段。这些差异通常是因为远端后端代码主动忽略了前端传值,并采用关联覆盖、自动计算或默认补全所致。
|
||||
|
||||
> **备注**:
|
||||
> 1. 根据梳理,完全被远端忽略的、只作为返回展示的字段已经从本地/远端的 `Create`、`Update` Schema 中彻底**剔除 (已删)**,不再作为入参推送。
|
||||
> 2. 标有 **[🔥远端接收并参与逻辑计算,但最终与本地不一致]** 的字段没有被删,作为强逻辑关联字段保留。
|
||||
|
||||
## 1. contract_settlement (合同结算)
|
||||
|
||||
### Create 请求 (`ContractSettlementCreate`)
|
||||
- **`contract_type` (合同类型)**: **(从 Schema 彻底剔除)** 远端完全不接收本地传值,根据关联逻辑自动赋予了实际类别(如 `'PC'`, `'GJ'`, `'E'`)。
|
||||
- **`contract_price` (合同总额)**: Create不需要传(本地本身无该入参)。远端在创建时直接从近端 Contract 数据库查取并覆盖。
|
||||
|
||||
### Update / Plan Update 请求 (`ContractSettlementUpdate` 等)
|
||||
- **`plan_complete_date`**: **[🔥远端接收并参与逻辑计算,但最终与本地不一致]** 远端接收该字段,主要作用于 `clean_plan_nodes` 数据清洗以保证非法边界节点被剔除,同时可能经过远端状态与明细上托更新,使得终值可能扭转。
|
||||
- **`complete_price` / `status` / `delay_days` / `statistic_date` / `actual_start_date`**: 远端自动计算累加的衍生只读字段,均不在 Create / Update Schema 范畴中,故不维护入参。
|
||||
|
||||
## 2. construction_task & construction_task_detail (施工任务及明细)
|
||||
|
||||
### Create 请求 (`ConstructionTaskCreate`)
|
||||
- **`contract_quantity` (合同工程量)**: **(已从 Create Schema 彻底剔除)** 远端由于 `create_construction` 函数底层逻辑完全不读此字段,现已被安全双端剪除。不在初始创建时推送。
|
||||
- **`plan_start_date` / `plan_complete_date`**: **[🔥远端接收并参与逻辑计算,但最终与本地不一致]** 远端校验WBS结构树约束时会接收这俩参数进行合规计算,如果超出父子节点范围,存在自动修正或打回改写的逻辑。
|
||||
|
||||
### Update / Plan Update 请求 (`ConstructionTaskUpdate` 及明细)
|
||||
- **`contract_quantity` (合同工程量)**: **[🔥远端接收并参与逻辑计算,但最终与本地不一致]** 在针对 `ConstructionPlanUpdate` 更新计划节点时,远程接受本字段控制计算与校验完成率基准,但仍可能会受 WBS 重制。
|
||||
- **`complete_quantity` / `complete_rate` / `rate` / `status` / `actual_complete_date`**: 纯内部状态更新触发、只读汇总,本地本来就未放至 Update Schema 内进行提交。
|
||||
|
||||
## 3. supplier (供应商)
|
||||
|
||||
### 字段表现
|
||||
- **`city_name`, `province_name`, `country_name`**: Response专用字段。本地不推,仅仅是远端依托外部库映射在接口返回中补全的只读显示。
|
||||
|
||||
## 4. company (组织/公司)
|
||||
|
||||
### 字段表现
|
||||
- **`parent_name` (父级机构名称)**: Response专用显示字段。远端依赖 `parent_id` 自动向上追溯返回字段。
|
||||
|
||||
## 5. production (产值等)
|
||||
|
||||
### Create / Update 请求
|
||||
- **`is_exist`**: **[🔥远端接收并参与逻辑计算,但最终与本地不一致]** 本地推流中有 `is_exist = True`,且远端后端提取了 `production_data.is_exist` 进行存入判断(确实参与了代码落库前置过滤逻辑),但最后远程抓回验证时为 `None`,这归因于远端的废弃映射和覆盖逻辑。该字段须保留不能删。
|
||||
Reference in New Issue
Block a user