news 2026/10/3 19:52:55

PanWatch 单元测试工程实践:100+ 测试文件背后的质量保障体系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PanWatch 单元测试工程实践:100+ 测试文件背后的质量保障体系

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/pytest128
行情数据 SDKpackages/marketdata/tests/pytest24
Agent 运行时packages/pan-agent-runtime/tests/pytest7
其他 Agent 包(token 计量 / 工具研究)packages/pan-agent-*/tests/pytest2
前端frontend/tests/Vitest + jsdom39

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 同时支持中英文,硬编码文案是重灾区:

  1. 静态扫描器:check-i18n-literals.mjs 用 TypeScript AST 遍历src/与共享包源码,揪出所有绕过翻译函数的字面量,并校验 key 在zh-CN/en-US两份语言资源里都存在;
  2. CI 强制:frontend-i18n.yml 在前端文件变更的 PR 上执行pnpm check:i18n,不过则合入失败;
  3. 检查器自己也受测: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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 19:52:55

Spark Streaming 吞吐量压测:数据速率、批处理时间与资源容量评估

Spark Streaming 吞吐量压测:数据速率、批处理时间与资源容量评估Spark Streaming 是基于 Spark Core 构建的流处理框架,采用微批处理模型,将实时数据流视为一系列小批量 RDD 来处理。在实际应用中,评估和优化 Spark Streaming 的…

作者头像 李华
网站建设 2026/10/3 19:51:26

2026国庆学生行李箱推荐:热门型号实测对比,选对箱包告别出行焦虑

国庆七天假,对大学生来说是一年里最值得期待的出行窗口。回家、旅行、实习往返,行李箱几乎是刚需。但很多人都有过类似的经历:轮子推起来嘎吱作响,在高铁站水泥地上拖行像拉着一台拖拉机;托运回来箱面多了几道划痕&…

作者头像 李华
网站建设 2026/10/3 19:49:29

U-Boot网络子系统深度解析:从net、mac到phy的调试与移植实战

1. 从一次网口不亮说起:U-Boot网络子系统的整体骨架板子上电,串口打印一路跑到U-Boot命令行,ping一下网关,结果返回ping failed; host 192.168.1.1 is not alive。这种场景做过嵌入式的人基本都遇到过。网口灯不亮、PHY识别不到、…

作者头像 李华
网站建设 2026/10/3 19:34:57

OpenClaw 动态 - 2026-W11:ClawHub Skills 与 gateway 的 PR 实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 19:28:46

大模型——基于Spring AI服务,开发MCP服务并接入TaoToken统一通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华