数据源测试

📎 引用文件

本文引用的文件 - agent/tests/test_akshare_loader.py - agent/tests/test_yahoo_loader.py - agent/tests/test_tushare_loader.py - agent/tests/test_loader_retry_helpers.py - agent/tests/test_eastmoney_loader.py - agent/tests/test_yfinance_crypto.py - agent/tests/conftest.py

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向 Vibe-Trading 的数据源测试,系统化说明数据加载器测试框架、数据验证规则与异常处理测试。文档覆盖多数据源(AkShare、Yahoo Finance、Tushare、东方财富等)的兼容性测试、数据格式转换测试与性能基准测试思路;并给出来自实际代码库的测试示例路径,展示如何验证各数据源的正确性与稳定性。同时记录测试数据管理、Mock 数据生成、真实数据验证策略,以及网络异常处理、重试机制与超时处理的测试方法。最后总结数据源测试自动化、数据质量监控与测试数据版本管理的最佳实践。

项目结构

仓库在 agent/tests 下按“数据源/功能”组织大量测试用例,围绕 backtest.loaders.* 模块进行隔离化、可重复的单元测试与端到端测试。关键要点: - 每个数据源通常有独立的测试文件,聚焦路由、映射、归一化、批量容错等特性。 - 通过 pytest fixture 与环境隔离,避免测试间污染。 - 使用 monkeypatch/patch 对第三方客户端或网络层进行 Mock,确保测试不依赖外部网络。 - 提供可选的真实 API 集成测试(如 Tushare E2E),通过环境变量开关控制。

graph TB subgraph "测试入口" conftest["conftest.py<br/>环境隔离与路径设置"] end subgraph "数据源测试" akshare["test_akshare_loader.py"] yahoo["test_yahoo_loader.py"] tushare["test_tushare_loader.py"] eastmoney["test_eastmoney_loader.py"] yfinance_crypto["test_yfinance_crypto.py"] retry["test_loader_retry_helpers.py"] end conftest --> akshare conftest --> yahoo conftest --> tushare conftest --> eastmoney conftest --> yfinance_crypto conftest --> retry

图表来源 - agent/tests/conftest.py:1-46

章节来源 - agent/tests/conftest.py:1-46

核心组件

章节来源 - agent/tests/conftest.py:16-46 - agent/tests/test_loader_retry_helpers.py:1-16

架构总览

下图展示了数据源测试的整体流程:测试通过 fixture 注入 Mock,调用 DataLoader.fetch 或内部方法,断言输出 DataFrame 的结构、索引、数值与行为(如批量容错、归一化、路由)。

sequenceDiagram participant T as "测试用例" participant L as "DataLoader" participant C as "客户端/网络层(被Mock)" participant N as "网络/第三方API" T->>L : 调用 fetch(代码, 起止日期, 周期) L->>C : 根据符号类型选择接口/映射 C-->>N : 发起请求(被Mock拦截) N-->>C : 返回原始数据(或错误) C-->>L : 标准化为OHLCV DataFrame L-->>T : 返回结果字典 {symbol : DataFrame} Note over T,L : 断言列名、索引、数值、空值、批量容错等

图表来源 - agent/tests/test_yahoo_loader.py:229-306 - agent/tests/test_eastmoney_loader.py:75-159 - agent/tests/test_tushare_loader.py:151-255

详细组件分析

AkShare 数据源测试

flowchart TD Start(["开始"]) --> Route["符号路由判断"] Route --> |ETF| ETF["调用ETF历史接口"] Route --> |外汇| FX["调用外汇历史接口"] Route --> |A股| A["调用A股历史接口"] ETF --> Normalize["标准化列名/填充缺失字段"] FX --> Normalize A --> Normalize Normalize --> End(["返回DataFrame"])

图表来源 - agent/tests/test_akshare_loader.py:33-76 - agent/tests/test_akshare_loader.py:119-177

章节来源 - agent/tests/test_akshare_loader.py:1-177

Yahoo/YFinance 数据源测试

sequenceDiagram participant T as "测试用例" participant Y as "Yahoo DataLoader" participant M as "yahoo_client.get_chart(被Mock)" T->>Y : fetch(代码列表, 起止日期, 周期) Y->>M : get_chart(symbol, period1, period2, interval) M-->>Y : 返回行列表 Y->>Y : 归一化为OHLCV DataFrame(时间戳/列名) Y-->>T : 返回{symbol : DataFrame}

图表来源 - agent/tests/test_yahoo_loader.py:56-128 - agent/tests/test_yahoo_loader.py:130-227 - agent/tests/test_yahoo_loader.py:229-306 - agent/tests/test_yfinance_crypto.py:16-71 - agent/tests/test_yfinance_crypto.py:86-148

章节来源 - agent/tests/test_yahoo_loader.py:1-320 - agent/tests/test_yfinance_crypto.py:1-148

Tushare 数据源测试

flowchart TD S(["开始"]) --> Type{"符号类型"} Type --> |A股| Stock["daily + adj_factor"] Type --> |ETF| Fund["fund_daily + fund_adj"] Type --> |指数| Index["index_daily"] Type --> |港股| HK["hk_daily"] Type --> |美股/加密| Skip["跳过并警告"] Stock --> Adj{"是否有复权因子?"} Adj --> |是| Adjust["应用前复权"] Adj --> |否| Drop["丢弃该标的"] Fund --> Adj2{"是否有复权因子?"} Adj2 --> |是| Adjust2["应用前复权"] Adj2 --> |否| Drop2["丢弃该标的"] Index --> NoAdj["不应用复权"] HK --> NoAdj Adjust --> Out["返回DataFrame"] Adjust2 --> Out NoAdj --> Out Drop --> Out Drop2 --> Out Skip --> Out

图表来源 - agent/tests/test_tushare_loader.py:31-117 - agent/tests/test_tushare_loader.py:151-255 - agent/tests/test_tushare_loader.py:273-330 - agent/tests/test_tushare_loader.py:409-474

章节来源 - agent/tests/test_tushare_loader.py:1-474

东方财富数据源测试

sequenceDiagram participant T as "测试用例" participant E as "东方财富 DataLoader" participant R as "resolve_secid(被Mock)" participant K as "fetch_kline(被Mock)" T->>E : fetch(代码, 起止日期, 周期) E->>R : 解析证券ID R-->>E : 返回secid E->>K : 拉取K线(传入klt/beg/end) K-->>E : 返回行列表 E->>E : 标准化为OHLCV DataFrame E-->>T : 返回{symbol : DataFrame}

图表来源 - agent/tests/test_eastmoney_loader.py:75-159 - agent/tests/test_eastmoney_loader.py:166-192

章节来源 - agent/tests/test_eastmoney_loader.py:1-192

通用重试与缓存测试

flowchart TD Start(["开始"]) --> CheckBudget["检查剩余预算"] CheckBudget --> |过期| Timeout["抛出TimeoutError"] CheckBudget --> |未过期| Try["执行fn()"] Try --> Ok{"成功?"} Ok --> |是| Return["返回结果"] Ok --> |否| Transient{"是否瞬态异常?"} Transient --> |是| Backoff["等待退避"] --> Retry["重试计数+1"] --> CheckBudget Transient --> |否| Propagate["立即传播异常"]

图表来源 - agent/tests/test_loader_retry_helpers.py:74-166 - agent/tests/test_loader_retry_helpers.py:228-343 - agent/tests/test_loader_retry_helpers.py:380-431 - agent/tests/test_loader_retry_helpers.py:433-521

章节来源 - agent/tests/test_loader_retry_helpers.py:1-521

依赖关系分析

graph LR Test["测试用例"] --> Loader["DataLoader"] Loader --> Client["客户端/网络层(Mock)"] Loader --> Cache["缓存(可选)"] Test --> Conftest["conftest 环境隔离"]

图表来源 - agent/tests/conftest.py:16-46 - agent/tests/test_loader_retry_helpers.py:228-343

章节来源 - agent/tests/conftest.py:16-46 - agent/tests/test_loader_retry_helpers.py:228-343

性能考量

[本节为一般性指导,不直接分析具体文件]

故障排查指南

章节来源 - agent/tests/test_tushare_loader.py:409-474 - agent/tests/test_yahoo_loader.py:229-306 - agent/tests/test_eastmoney_loader.py:125-159

结论

Vibe-Trading 的数据源测试体系以模块化、可隔离、可重复为核心,覆盖路由、映射、归一化、批量容错、重试与缓存等关键环节。通过对 AkShare、Yahoo/YFinance、Tushare、东方财富等数据源的细致断言,确保了多市场、多周期的数据一致性与稳定性。建议在生产环境中延续这些测试模式,并结合数据质量监控与测试数据版本管理,持续保障数据管道的可靠性。

[本节为总结性内容,不直接分析具体文件]

附录

[本节为一般性指导,不直接分析具体文件]