FinDataHub
cd076018ba
test: 统一测试入口 + 真实 MySQL 集成测试
## 统一入口 run_all_tests.py
跑一次全量测试要记住四件事,任何一条忘了结论就是错的:
1. 每套件用哪个 venv(findatahub_core 只装在部分 venv 里)
2. 必须注入 PYTHONPATH,否则验的是已安装的旧版本
3. Scripts/bin/tests 需要 httpx,选错 venv 在收集阶段直接报错
4. **不能并行**——两个 pytest 会互踩系统临时目录,报 pytest-of-root
EEXIST 假失败(表现为几十个 errors,看着像大回归)
摩擦本身就是回归风险的来源,固化成脚本。四个设计点:
- 解释器按能力选:每套件声明 requires,扫描 Services/*/.venv 挑第一个
满足的;挑不到 exit 2 并列出缺什么,绝不用错的 venv 硬跑出假结果
- 强制注入 PYTHONPATH,源码目录排最前
- **每套件独立 --basetemp**(.pytest-cache/<suite>/):从根上消除 tmpdir
争用,不依赖"记得串行",也不去删系统临时目录
- 摘要提取要求「数字+状态词」相邻且 stdout 优先,避免把
(Background on this error at: sqlalche.me/...) 当成统计行
实测 6 套件 14.9s;加 --include-swift --include-frontend 共 8 套件 37s。
**重要发现**:scripts 从 205 → 252——多的 47 条是 test_rss_fetcher.py,
此前因 akshare venv 缺 httpx 一直被 --ignore 跳过。这批用例一直存在且可用,
只是从没在本机跑过。
## 真实 MySQL 集成测试
findatahub-core/tests/integration/,8 条用例。
为什么 fake 不够:test_db_replace_guard.py 用 Fake 游标验了代码路径,但
Fake 验不了三件事——事务是否真的回滚(Fake 的 rollback 只是置标志位)、
跨 chunk 失败是否留下半成品(Fake 不会真提交,这个场景永远复现不出来)、
熔断时表是否真的没动(需真实读行数)。
隔离:每次 fixture 新建 fdh_it_replace_<随机8位> 空库,用完 DROP;
库名带前缀且 DROP 前再断言。不读现有配置、不碰现有库。
无 MYSQL_PASSWORD 时整组 skip,CI 无 MySQL 不会变红。
**证伪验证**:把 replace() 临时改回「每 chunk 提交」旧行为,该套件报
「回滚不完整:表内行数既不是旧值 1000,说明留下了半成品数据」→ 测试有牙。
恢复后复跑 8 passed,生产库行数前后一致(news_flash 368346 /
stock_daily 8158172),无 fdh_it_% 残留。
--with-integration 开关默认关闭(要真实库且会建临时库)。
2026-10-26 20:55:52 +08:00
..
2026-10-26 20:55:31 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 23:34:51 +08:00
2026-09-19 00:12:54 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-19 00:27:21 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-19 08:38:27 +08:00
2026-10-26 20:55:31 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-19 17:49:33 +08:00
2026-10-26 20:55:31 +08:00
2026-09-18 22:37:32 +08:00
2026-09-19 00:21:44 +08:00
2026-10-26 20:55:31 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-10-26 20:55:31 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-10-26 20:55:31 +08:00
2026-09-18 22:37:32 +08:00
2026-10-26 20:55:31 +08:00
2026-09-19 22:37:19 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-10-26 20:55:52 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-18 22:37:32 +08:00
2026-09-19 22:42:00 +08:00
2026-09-19 17:49:33 +08:00