PanWatch 单元测试工程实践:100+ 测试文件背后的质量保障体系
【免费下载链接】PanWatchPanWatch — AI stock monitoring for A-shares, HK & US markets, powered by TradingAgents. Portfolio insights, real-time alerts & automated reports.|盯盘侠:覆盖 A股/港股/美股的 AI 盯盘、持仓分析、实时提醒与自动报告。项目地址: https://gitcode.com/GitHub_Trending/pa/PanWatch
PanWatch 是一款支持 A股、港股、美股三大市场的自托管 AI 盯盘工具,核心能力包括持仓分析、实时价格提醒、K线技术分析以及基于 TradingAgents 的多智能体深度研究。一个每天盯住行情、自动推送提醒的 AI 应用,最怕的就是"改一行崩一片"。PanWatch 用200 个测试文件、1280 多个用例(162 个 Python 测试文件 + 39 个前端测试文件)构建了四层质量保障:单元测试 → 架构守护 → 多语言校验 → AI Agent 评测门禁。本文带你拆解这套体系是如何落地到每个文件里的。
测试版图总览:200+ 测试文件如何分工
PanWatch 采用 monorepo 结构,测试随代码走,各包独立维护自己的测试目录:
| 层级 | 位置 | 框架 | 测试文件数 |
|---|---|---|---|
| 后端主项目 | tests/ | pytest | 128 |
| 行情数据 SDK | packages/marketdata/tests/ | pytest | 24 |
| Agent 运行时 | packages/pan-agent-runtime/tests/ | pytest | 7 |
| 其他 Agent 包(token 计量 / 工具研究) | packages/pan-agent-*/tests/ | pytest | 2 |
| 前端 | frontend/tests/ | Vitest + jsdom | 39 |
Python 侧共约 1110 个测试函数,前端约 170 个用例。测试按业务域命名,比如 test_quote_routing.py 守护行情数据路由、test_tradingagents_auto_trigger.py 守护 AI 深度分析触发逻辑、AssistantSidebar.test.tsx 守护 AI 助手侧边栏交互——看文件名就知道它在保什么。
一键执行:make test 背后的完整链路
日常开发只需要记住一条命令。Makefile 里定义了两个测试目标:
make test—— 跑全部单测,默认不发送真实通知;make test-notify—— 加上--notify参数,恢复真实通知发送,用于集成验证。
提交推送前还有最后一道闸门:scripts/pre-push 钩子会执行python -m pytest tests/ -x -q,任一用例失败立即中止推送(通过make install-hooks安装)。
conftest.py 里的三个工程细节
所有后端测试共享 tests/conftest.py,其中三个设计值得新手借鉴:
1️⃣ 用中文 docstring 当测试名。pytest_itemcollected 钩子 会把测试函数的中文文档字符串替换进-v输出,跑测试时看到的不是test_xxx,而是"模拟盘账户应正确初始化"这类人话,阅读成本骤降。
2️⃣ 自动屏蔽真实通知。PanWatch 会向多渠道推送股价提醒,若测试误触发会"惊动用户"。autouse fixture 默认把NotifierManager的发送方法替换为 no-op,只有显式传入--notify才恢复真实发送——单测零副作用。
3️⃣ 缓存隔离 + 幂等建表。行情采集层带 TTL 内存缓存,fixture 在每个用例前后清空 K线/资金流/指数缓存,防止用例互相污染;会话级 fixture 再幂等建表,保证 CI 全新环境直接可跑。
架构守护测试:把"代码结构"也纳入断言
多数项目只测功能,PanWatch 还测结构。test_architecture_boundaries.py 用 AST 解析整个src/platform与src/modules的 import 关系,强制两条铁律:底层平台包不得反向依赖业务模块、业务模块之间不得跨包偷用对方的存储层。配套的 test_module_ownership.py 则断言每个模块的实现文件确实在自己名下。这类"元测试"在重构和 AI 辅助编码时代价值极大——它让架构腐化在合并前就被测试红灯拦住。
前端双层防护:Vitest + i18n 静态检查
前端测试由 Vitest 驱动,vitest.config.ts 使用 jsdom 环境模拟浏览器,重点覆盖 AI 助手组件、通知中心、组合页数据流等 39 个文件。
更巧妙的是多语言防护。PanWatch 同时支持中英文,硬编码文案是重灾区:
- 静态扫描器:check-i18n-literals.mjs 用 TypeScript AST 遍历
src/与共享包源码,揪出所有绕过翻译函数的字面量,并校验 key 在zh-CN/en-US两份语言资源里都存在; - CI 强制:frontend-i18n.yml 在前端文件变更的 PR 上执行
pnpm check:i18n,不过则合入失败; - 检查器自己也受测:i18n-key-checker.test.ts 用 fixtures 里的"好文件/坏文件"双向验证扫描器本身——工具人也要有人管。后端侧的 test_i18n_system_outputs.py 则专门回归"非 React 表面"(如 AI 工具描述)的输出一律不泄漏中文。
AI Agent 评测门禁:make eval 守护智能体行为
对 AI 功能做确定性断言很难,PanWatch 的方案是"规则断言优先、语义评分补充",入口是 tests/eval/:
- 用例即契约:chat_cases.py 含 24 条工具循环用例、structured_cases.py 含 18 条结构化输出解析 golden 用例。每条用例断言:该调的工具调了、不该调的没调、答案数值必须引用工具结果(有据性)、工具失败时优雅降级不编造;
- 白名单安全:动作只允许 ASSISTANT_TOOLS 注册的只读工具,AI 助手绝无写操作空间;
- 门禁化:run_eval.py 的通过率低于阈值(默认 0.9)时退出码非 0,官方建议改
prompts/*.txt或工具 schema 后必跑; - LLM-as-judge 可选:追加
--judge用另一个模型对答案做相关性/清晰度语义评分。
写在最后:普通用户能带走什么
对使用者而言,这套体系换来的是可预期的稳定:价格提醒不会误推(conftest 全链路屏蔽)、中英文界面不会串味(i18n 双层扫描)、AI 助手不会越权操作(工具白名单 + 有据性断言)、多市场行情数据路由有据可查(128 个后端测试文件)。对想借鉴的开发者,三个最值得抄作业的模式是:中文 docstring 即测试名、把架构约束写成断言、给 AI 功能建 golden set 门禁。想动手体验,仓库可以这样获取:
git clone https://gitcode.com/GitHub_Trending/pa/PanWatch make test跑通 1280 多个用例的那一刻,你对这个项目的质量会有和现在完全不同的信心。
【免费下载链接】PanWatchPanWatch — AI stock monitoring for A-shares, HK & US markets, powered by TradingAgents. Portfolio insights, real-time alerts & automated reports.|盯盘侠:覆盖 A股/港股/美股的 AI 盯盘、持仓分析、实时提醒与自动报告。项目地址: https://gitcode.com/GitHub_Trending/pa/PanWatch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考