Files
sanguo_moziplus_v2/docs/test-guide.md
cfdaily f7fbdac89c chore: simayi-approved changes - lint fixes, toolchain improvements, healthz
All changes reviewed and APPROVED in PR #12 (Review ID: 40):
- toolchain_routes: webhook repo/org format compat, content dedup (sha256), closed issue filter
- dispatcher: inform mail crash 误标 done 修复
- ticker: cleanup and improvements
- healthz endpoint
- conftest: integration/e2e deselect markers
- docs: design docs, test-guide updates
- various lint/whitespace fixes across 30 files
2026-06-09 23:41:53 +08:00

109 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# moziplus v2.0 测试操作指南
> 日期:2026-06-05
> 对应设计文档:docs/test-plan-e2e-v27.md v3.0.1
> 测试代码路径:`~/.sanguo_projects/sanguo_moziplus_v2/tests/`
---
## 什么时候跑什么
| 场景 | 命令 | 耗时 | 说明 |
|------|------|------|------|
| **改了某个模块** | `pytest tests/unit/test_spawner.py` | <5s | 只跑改动的模块对应的单元测试 |
| **改了 API 层** | `RUN_INTEGRATION=1 pytest tests/integration/` | ~1min | 跑全部集成测试 |
| **提交前快速验证** | `pytest` | ~2min | 默认排除 integration 和 e2e |
| **含集成测试** | `RUN_INTEGRATION=1 pytest` | ~5min | 包含 integration 测试 |
| **部署前全量验证** | `RUN_INTEGRATION=1 pytest` | ~60min | 含 e2e,真实 Agent |
| **只跑 E2E 场景** | `RUN_INTEGRATION=1 pytest tests/e2e/test_e2e_scenarios.py` | ~30min | 串行,一个跑完再下一个 |
| **只跑 E2E 压力** | `RUN_INTEGRATION=1 pytest tests/e2e/test_e2e_stress.py` | ~10min | 并发测试 |
## 按标记筛选
```bash
pytest -m broadcast # 广播相关
pytest -m mail # 邮件相关
pytest -m state_machine # 状态机
pytest -m classify # Classify Outcome
pytest -m review # 审查/Rebuttal
```
## 改了什么跑什么(速查表)
| 改的文件 | 跑什么 |
|---------|--------|
| `src/blackboard/db.py` | `pytest tests/unit/test_state_machine.py` |
| `src/daemon/spawner.py` | `pytest tests/unit/test_spawner.py tests/unit/test_classify_outcome.py` |
| `src/daemon/ticker.py` | `pytest tests/unit/test_broadcast_claim.py tests/integration/test_ticker_integration.py` |
| `src/daemon/dispatcher.py` | `pytest tests/unit/test_dispatcher.py` |
| `src/daemon/counter.py` | `pytest tests/unit/test_counter.py` |
| `src/daemon/router.py` | `pytest tests/unit/test_router.py` |
| `src/api/mail_routes.py` | `pytest tests/integration/test_api_mail.py` |
| `src/api/blackboard_routes.py` | `pytest tests/integration/ -k task` |
| `src/daemon/review.py` | `pytest tests/unit/test_review.py tests/integration/test_review_integration.py` |
| `frontend/` | 不在本范围 |
## E2E 怎么跑
### 场景测试(严格串行,一个一个来)
```bash
# 1. 确认 daemon 在线
pm2 list | grep sanguo-moziplus-v2
# 2. 逐个跑场景测试(关键:一个完成再跑下一个)
RUN_INTEGRATION=1 pytest tests/e2e/test_e2e_scenarios.py::TestS9RealAgentDispatch -v
# → 通过?跑下一个。失败?分析根因、修复、重跑当前,不跳过
RUN_INTEGRATION=1 pytest tests/e2e/test_e2e_scenarios.py::TestS10FullChain -v
# → 以此类推,逐个推进
# 或者一次跑全部(pytest 默认串行,但无法在失败时停下来分析)
RUN_INTEGRATION=1 pytest tests/e2e/test_e2e_scenarios.py -v --exitfirst
# --exitfirst 遇到第一个失败就停,方便定位问题
```
**串行原则**:一个 case 跑完 → 收集结果 → 根因分析(如有问题)→ 修复 → 重跑当前 → 通过后再跑下一个。用时间换可靠性。
### 压力测试(场景全通过后)
```bash
RUN_INTEGRATION=1 pytest tests/e2e/test_e2e_stress.py -v
```
### 跑完后检查残留
```bash
curl -s http://localhost:8083/api/projects | python3 -c "
import sys, json
projs = json.load(sys.stdin)
e2e = [p['id'] for p in projs if p['id'].startswith('e2e-')]
print(f'e2e 残留: {len(e2e)} 个') if e2e else print('无残留 ✅')
"
```
## 测试数据清理
```bash
# 手动清理所有 e2e 残留
cd ~/.sanguo_projects/sanguo_moziplus_v2/data
sqlite3 registry.db "DELETE FROM projects WHERE id LIKE 'e2e-%';"
rm -rf e2e-v27-*
```
## 三层测试对照
```
单元测试(快,mock) → 验证逻辑正确性,随便跑不污染
集成测试(中,tmp_path) → 验证 API + DB 交互,随便跑不污染
E2E(慢,真实 Agent) → 验证完整链路,需要 RUN_INTEGRATION=1,测完要清理
```
## 关键规则
1. **只有 E2E 会 spawn 真实 Agent**,单元和集成不会
2. **直接跑 `pytest` 是安全的**integration 和 e2e 全部被排除(需 `RUN_INTEGRATION=1` 才跑)
3. **E2E 场景测试串行**,一个完成再下一个,失败要分析根因再继续
4. **E2E 压力测试并行**,场景测试全通过后再跑
5. **测试数据用 `e2e-` 前缀**,atexit 兜底清理,手动清理见上方