195 lines
6.4 KiB
Markdown
195 lines
6.4 KiB
Markdown
# 测试指南
|
||
|
||
本文档说明三件事:
|
||
- 单元测试怎么跑。
|
||
- 集成测试怎么组织。
|
||
- 测试辅助工具如何使用,尤其是远程 ECM 环境初始化工具。
|
||
|
||
## 1. 测试分层
|
||
|
||
### 1.1 单元测试
|
||
|
||
位置:`tests/unit/`
|
||
|
||
目标:
|
||
- 校验状态机不变量、事件约束、策略辅助逻辑。
|
||
- 校验 datasource/handler 工具链、配置严格性、导入面稳定性。
|
||
- 对具体 domain 的 update/create 行为做快速回归。
|
||
|
||
单元测试取舍原则:
|
||
- 优先测文档里承诺的行为语义,不优先测单纯转发、setter、空包装器。
|
||
- 如果一个测试只是在断言“函数 A 调了函数 B”,但不验证最终行为,通常应该删掉或改写成行为测试。
|
||
- 如果需要 test double,优先让它承载真实行为断言,不保留仅为凑接口而存在的空壳类。
|
||
|
||
常用命令:
|
||
- 全量单元测试:`pytest tests/unit -q`
|
||
- 指定文件:`pytest tests/unit/test_update_ops.py -q`
|
||
|
||
适用场景:
|
||
- 修改 `sync_state_machine/` 公共逻辑。
|
||
- 修改某个 domain 的 handler/strategy。
|
||
- 校验 schema 相关逻辑没有引入行为回退。
|
||
|
||
### 1.2 集成测试
|
||
|
||
位置:`tests/integration/`
|
||
|
||
目标:
|
||
- 覆盖 pipeline 级行为,包括 load/bind/create/update/poll/persist。
|
||
- 校验多节点、多轮次、mock datasource 与 UI smoke 场景。
|
||
- 验证运行配置、状态机配置和工具链连通性。
|
||
|
||
常用命令:
|
||
- 全量集成测试:`pytest tests/integration -q`
|
||
- UI 烟测:`pytest tests/integration/test_ui_api_smoke.py -q`
|
||
- 工具链专项:`pytest tests/integration/test_toolchain_config_and_graph.py -q`
|
||
|
||
适用场景:
|
||
- 修改 pipeline、collection、状态机执行路径。
|
||
- 修改持久化或跨 domain 依赖行为。
|
||
- 修改运行配置解析、注册表装配等入口逻辑。
|
||
|
||
### 1.3 脚本化大规模回归
|
||
|
||
位置:`scripts/auto_test_domains/`
|
||
|
||
目标:
|
||
- 用“多轮数据集 + 报告”的方式覆盖复杂业务 domain。
|
||
- 适合真实接口联调、回归复现、差异收敛分析。
|
||
|
||
特点:
|
||
- 这类脚本不直接纳入 pytest。
|
||
- 它们更偏向测试编排与问题定位,而不是轻量级快速回归。
|
||
|
||
相关文档:
|
||
- `docs/auto_test_spec/agent_auto_test_method.md`
|
||
|
||
## 2. 远程环境初始化工具
|
||
|
||
位置:`tools/remote_env.py`
|
||
|
||
这个工具是给真实 ECM 环境联调用的最小控制器,提供 4 个命令:
|
||
- `clear`:停止服务、恢复 `.env`、清空自动测试专用 CouchDB 数据库。
|
||
- `init`:停止服务,按 JSONL 数据目录执行 `run.py restore-database` 恢复测试数据库。
|
||
- `run`:启动远程 ECM 服务,不阻塞当前命令。
|
||
- `stop`:关闭远程 ECM 服务,并恢复原始 `.env`。
|
||
|
||
它不是 pipeline 执行器,只负责测试环境的基础生命周期管理。
|
||
|
||
### 2.1 配置项
|
||
|
||
示例配置:`tools/remote_env.example.yaml`
|
||
|
||
核心配置:
|
||
- `couchdb.base_url` / `couchdb.database` / `couchdb.username` / `couchdb.password`
|
||
- `service.ecm_root`
|
||
- `service.python_path`
|
||
- `data.data_dir`
|
||
- `env_file.path`
|
||
- `env_file.overrides`
|
||
|
||
按命令的最低要求:
|
||
- `run` / `stop`:只要求 `service.*` 可用。
|
||
- `clear`:要求 `service.*` 和 `couchdb.*` 可用。
|
||
- `init`:要求 `service.*`、`couchdb.*`、`data.*` 全部可用。
|
||
|
||
可选配置:
|
||
- `service.start_command`
|
||
- `service.restore_command`
|
||
- `service.ready_url`
|
||
- `service.log_file`
|
||
- `service.env`
|
||
- `env_file.restore_on_stop`
|
||
|
||
支持占位符:
|
||
- `${PROJECT_ROOT}`:当前仓库根目录。
|
||
- `${CONFIG_DIR}`:配置文件所在目录。
|
||
- `${ECM_ROOT}`:`service.ecm_root` 的值。
|
||
- `${PYTHON}`:`service.python_path` 的值。
|
||
- `${DATA_DIR}`:`data.data_dir` 的值。
|
||
- `${COUCHDB_DATABASE}`:`couchdb.database` 的值。
|
||
- `${COUCHDB_USERNAME}`:`couchdb.username` 的值。
|
||
- `${COUCHDB_PASSWORD}`:`couchdb.password` 的值。
|
||
- `${COUCHDB_URL}`:`couchdb.url` 的值。
|
||
- `${COUCHDB_PORT}`:`couchdb.port` 的值。
|
||
|
||
### 2.2 基本用法
|
||
|
||
1. 复制示例配置并填入真实路径。
|
||
2. 先执行 `init` 恢复测试数据库。
|
||
3. 再执行 `run` 启动远程服务。
|
||
4. 测试结束后执行 `stop`。
|
||
|
||
命令示例:
|
||
|
||
```bash
|
||
python tools/remote_env.py --config tools/remote_env.example.yaml init
|
||
python tools/remote_env.py --config tools/remote_env.example.yaml run
|
||
python tools/remote_env.py --config tools/remote_env.example.yaml stop
|
||
python tools/remote_env.py --config tools/remote_env.example.yaml clear
|
||
```
|
||
|
||
### 2.3 命令行覆盖
|
||
|
||
如果只想临时覆盖少数字段,可以直接传命令行参数:
|
||
|
||
```bash
|
||
python tools/remote_env.py \
|
||
--config tools/remote_env.example.yaml \
|
||
--db-name test_push_auto_tmp \
|
||
--ecm-root /data/ecm_app \
|
||
--python-path /data/venv/bin/python \
|
||
init
|
||
```
|
||
|
||
支持覆盖的字段:
|
||
- `--db-name`
|
||
- `--db-user`
|
||
- `--db-password`
|
||
- `--couchdb-base-url`
|
||
- `--couchdb-url`
|
||
- `--couchdb-port`
|
||
- `--ecm-root`
|
||
- `--python-path`
|
||
- `--data-dir`
|
||
- `--ready-url`
|
||
|
||
### 2.4 行为约束
|
||
|
||
- `clear` 和 `init` 会先执行停服,避免服务仍占用 CouchDB 连接。
|
||
- `init` 不会自动执行 `run`;数据库恢复和服务启动分开控制。
|
||
- `run` 如果检测到远端仓库下已有 `run.py` 进程在运行,会直接返回 `already_running`。
|
||
- `.env` 只覆盖 `env_file.overrides` 中声明的键,未声明的键会原样保留。
|
||
- 第一次覆盖 `.env` 时会自动备份,`stop` 和 `clear` 默认会恢复原始 `.env`。
|
||
- 进程状态写到 `runtime/remote_env/state.json`,不需要手工配置 pid 文件。
|
||
|
||
## 3. 推荐测试流程
|
||
|
||
### 3.1 本地开发回归
|
||
|
||
1. 先跑 `pytest tests/unit -q`。
|
||
2. 如果改动影响 pipeline,再跑目标集成测试。
|
||
3. 如果改动影响真实接口流程,再使用 `tools/remote_env.py` 管理远程环境。
|
||
4. 如果修改了配置语义或 pipeline 控制流,优先补一条直接覆盖设计语义的 pytest,而不是只补装配/转发测试。
|
||
|
||
### 3.2 真实接口联调
|
||
|
||
1. 用 `init` 恢复 ECM 测试库。
|
||
2. 用 `run` 拉起 ECM 服务。
|
||
3. 执行同步脚本或联调脚本。
|
||
4. 查看 `runtime/remote_env/` 下的状态文件与日志。
|
||
5. 完成后执行 `stop`。
|
||
|
||
### 3.3 复杂 domain 回归
|
||
|
||
1. 用 `scripts/auto_test_domains/` 中的 case 脚本准备多轮数据。
|
||
2. 先缩小到单个 domain 复现。
|
||
3. 确认差异与日志后,再扩大到聚合回归。
|
||
|
||
## 4. 相关文件
|
||
|
||
- `tests/README.md`
|
||
- `tools/remote_env.py`
|
||
- `tools/remote_env.example.yaml`
|
||
- `docs/operations.md`
|
||
- `docs/auto_test_spec/agent_auto_test_method.md` |