# 测试与调试 **本文引用的文件** - [vitest.config.mts](file://vitest.config.mts) - [test/index.spec.ts](file://test/index.spec.ts) - [test/env.d.ts](file://test/env.d.ts) - [test/tsconfig.json](file://test/tsconfig.json) - [package.json](file://package.json) - [tsconfig.json](file://tsconfig.json) - [src/index.ts](file://src/index.ts) - [src/command/index.ts](file://src/command/index.ts) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts) - [src/scheduler/index.ts](file://src/scheduler/index.ts) - [src/command/handlers/start.ts](file://src/command/handlers/start.ts) - [src/command/handlers/login.ts](file://src/command/handlers/login.ts) - [src/command/handlers/events.ts](file://src/command/handlers/events.ts) - [wrangler.jsonc](file://wrangler.jsonc) - [worker-configuration.d.ts](file://worker-configuration.d.ts) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向 Cosmoe Bot 的测试与调试实践,围绕以下目标展开: - 单元测试:基于 Vitest 与 @cloudflare/vitest-pool-workers 的配置与用法,覆盖 Worker 入口、命令处理器、API 客户端等模块。 - 集成测试:通过 cloudflare:test 提供的执行上下文与 SELF 端到端调用,验证从 Telegram 到 Worker 再到外部 API 的完整链路。 - 调试技巧:Wrangler 调试模式、浏览器开发者工具、日志分析与可观测性。 - 性能与压力测试:在本地与 Workers 环境中进行基准与压力评估的实施路径。 ## 项目结构 该项目采用 Cloudflare Workers + Vitest 测试框架,核心目录与职责如下: - src:业务逻辑入口、命令注册、调度任务、API 客户端 - test:Vitest 测试套件、类型声明与测试 TS 配置 - 根目录:Vitest 配置、Wrangler 配置、包脚本与类型生成 ```mermaid graph TB subgraph "测试层" VConf["vitest.config.mts"] TSpec["test/index.spec.ts"] TEnv["test/env.d.ts"] TTsc["test/tsconfig.json"] end subgraph "应用层" Entry["src/index.ts"] Cmd["src/command/index.ts"] Sched["src/scheduler/index.ts"] Client["src/client/cosmoe.ts"] Handlers["src/command/handlers/*.ts"] end subgraph "运行时配置" Wcfg["wrangler.jsonc"] Wtype["worker-configuration.d.ts"] Pkg["package.json"] TsMain["tsconfig.json"] end VConf --> TSpec TSpec --> Entry TSpec --> Sched Entry --> Cmd Cmd --> Handlers Entry --> Client Sched --> Client Wcfg --> Entry Wcfg --> Sched Pkg --> VConf TsMain --> Entry TsMain --> Cmd TsMain --> Sched TsMain --> Client Wtype --> Entry Wtype --> Sched ``` 图表来源 - [vitest.config.mts](file://vitest.config.mts#L1-L12) - [test/index.spec.ts](file://test/index.spec.ts#L1-L25) - [src/index.ts](file://src/index.ts#L1-L47) - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) - [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L800) - [package.json](file://package.json#L1-L24) - [tsconfig.json](file://tsconfig.json#L1-L46) 章节来源 - [vitest.config.mts](file://vitest.config.mts#L1-L12) - [test/index.spec.ts](file://test/index.spec.ts#L1-L25) - [src/index.ts](file://src/index.ts#L1-L47) - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) - [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L800) - [package.json](file://package.json#L1-L24) - [tsconfig.json](file://tsconfig.json#L1-L46) ## 核心组件 - Worker 入口与命令系统:负责初始化 Bot、注册命令与回调、设置菜单,并通过 webhook 回调接入 Cloudflare 运行时。 - 命令处理器:提供 start、login(交互式对话)、events、event_*、book_*、history、cancel_*、callbackQuery 等处理流程。 - API 客户端:封装对 Cosmoe API 的请求,包括认证、事件查询、用户资料、预订、优惠券、支付单号更新、变更/转移/取消等。 - 调度任务:定时拉取新活动并向已注册用户发送通知,同时维护最新活动 ID。 章节来源 - [src/index.ts](file://src/index.ts#L1-L47) - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) ## 架构总览 下图展示测试视角下的关键交互:Vitest 使用 @cloudflare/vitest-pool-workers 在本地启动 Workers 环境,通过 cloudflare:test 的执行上下文与 SELF 发起请求,从而覆盖 Worker 入口与调度器。 ```mermaid sequenceDiagram participant VT as "Vitest" participant CF as "cloudflare : test" participant SELF as "SELF" participant WR as "src/index.ts" participant SCH as "src/scheduler/index.ts" VT->>CF : "创建执行上下文
等待 waitUntil 完成" CF->>SELF : "发起请求到 /" SELF->>WR : "fetch(request, env, ctx)" WR-->>SELF : "返回 Response" SELF-->>CF : "断言响应内容" VT->>CF : "触发 scheduled 事件" CF->>SCH : "scheduled(controller, env, ctx)" SCH-->>CF : "完成通知逻辑" ``` 图表来源 - [test/index.spec.ts](file://test/index.spec.ts#L1-L25) - [src/index.ts](file://src/index.ts#L13-L46) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) ## 详细组件分析 ### 单元测试与 Vitest 配置 - 测试运行池:通过 @cloudflare/vitest-pool-workers 将 Vitest 与 Wrangler 配置绑定,确保测试在 Workers 环境中执行。 - 测试入口:使用 cloudflare:test 提供的辅助函数创建请求、执行上下文,并等待 waitUntil 中的异步任务完成。 - 类型与环境:通过 test/tsconfig.json 引入 @cloudflare/vitest-pool-workers 类型;test/env.d.ts 将 Env 注入到测试环境。 建议的测试设计模式 - 模块化:每个被测模块(命令处理器、API 客户端)独立编写测试文件,便于聚焦与维护。 - 模拟对象:对外部依赖(KV、Telegram API、Cosmoe API)进行模拟,避免真实网络与持久化。 - 断言策略:对响应文本、回调行为、KV 写入、异常抛出进行断言。 章节来源 - [vitest.config.mts](file://vitest.config.mts#L1-L12) - [test/index.spec.ts](file://test/index.spec.ts#L1-L25) - [test/env.d.ts](file://test/env.d.ts#L1-L4) - [test/tsconfig.json](file://test/tsconfig.json#L1-L9) ### Worker 入口与命令系统测试 - 入口测试要点:构造 Request,创建空执行上下文,调用 worker.fetch 并断言响应;使用 waitOnExecutionContext 等待后台任务。 - 命令注册:通过 setupCommands 安装对话插件与各命令处理器,测试应覆盖命令匹配、正则路由与回调查询。 - 环境变量:Bot 令牌、KV 绑定、Bot 信息等由 wrangler.jsonc 提供,测试需在相同环境下运行。 ```mermaid flowchart TD Start(["开始:构造请求"]) --> Ctx["创建执行上下文"] Ctx --> Fetch["调用 worker.fetch"] Fetch --> Wait["等待 waitUntil 完成"] Wait --> Assert["断言响应内容/状态"] Assert --> End(["结束"]) ``` 图表来源 - [test/index.spec.ts](file://test/index.spec.ts#L10-L18) - [src/index.ts](file://src/index.ts#L13-L46) 章节来源 - [src/index.ts](file://src/index.ts#L1-L47) - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [wrangler.jsonc](file://wrangler.jsonc#L18-L31) ### API 客户端测试策略 - 网络请求模拟:使用 fetch 的模拟实现,控制返回码与数据,覆盖成功、鉴权缺失、参数校验失败等分支。 - 错误场景:模拟网络异常、服务端错误、鉴权失败、参数不合法等。 - 异步操作:对所有异步方法进行超时与重试策略测试,确保 Promise 正常收敛。 - 数据契约:基于接口定义(如 ApiResponse、Event、UserProfile 等)编写结构化断言。 ```mermaid classDiagram class CosmoeClient { +getToken(username, password) +getEvents() +getEventDetail(eventId) +getProfile() +getMyBookings() +bookEvent(request) +changePassword(old, new) +getUserProfile() +getAvailableCoupons(eventId) +updatePaymentOrder(bookingId, orderId) +updateBookingNote(bookingId, note) +cancelBooking(bookingId) +selfReschedule(bookingId, slot) +selfTransfer(bookingId, username) +register(key, username, email, password, identity) +setCredentials(userId, token) +getCredentials() +isAuthenticated() } ``` 图表来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) 章节来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503) ### 命令处理器测试 - start 命令:验证消息回复内容与格式。 - login 交互:模拟用户输入用户名/密码,断言登录结果与 KV 写入。 - events 命令:断言事件列表构建与 Markdown 格式输出。 ```mermaid sequenceDiagram participant U as "用户" participant B as "Bot" participant H as "handleEventsCommand" participant C as "CosmoeClient" U->>B : "/events" B->>H : "调用处理器" H->>C : "getEvents()" C-->>H : "返回事件列表" H-->>U : "发送 Markdown 消息" ``` 图表来源 - [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L177-L184) 章节来源 - [src/command/handlers/start.ts](file://src/command/handlers/start.ts#L1-L6) - [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75) - [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27) ### 调度任务测试 - 场景设计:准备不同时间点的事件列表,验证“新增事件”过滤逻辑与 KV 最大 ID 更新。 - 测试数据:使用 COSMOE_STORAGE 存储 latestEventId,COSMOE_CREDENTIALS 存储用户凭证,模拟多用户通知。 - 环境隔离:通过 Wrangler 配置的 KV 绑定与 cron 触发器,在测试中以 scheduled 事件驱动。 ```mermaid flowchart TD S(["定时触发"]) --> Load["读取 latestEventId"] Load --> Fetch["调用 CosmoeClient.getEvents()"] Fetch --> Filter{"存在新事件?"} Filter -- 否 --> End(["结束"]) Filter -- 是 --> LoopUsers["遍历已注册用户"] LoopUsers --> Notify["bot.api.sendMessage(...)"] Notify --> Update["更新 latestEventId"] Update --> End ``` 图表来源 - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L177-L184) 章节来源 - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) - [wrangler.jsonc](file://wrangler.jsonc#L21-L31) ## 依赖关系分析 - 测试依赖:Vitest + @cloudflare/vitest-pool-workers;cloudflare:test 提供执行上下文与 SELF。 - 应用依赖:grammy 与 @grammyjs/conversations 实现对话与命令;KV 命名空间用于会话与凭证存储。 - 运行时依赖:Wrangler 提供 KV 绑定、cron 触发器与可观测性开关。 ```mermaid graph LR Pkg["package.json"] --> Vitest["@cloudflare/vitest-pool-workers"] Pkg --> Wrk["wrangler"] Vitest --> VConf["vitest.config.mts"] VConf --> TSpec["test/index.spec.ts"] TSpec --> Entry["src/index.ts"] Entry --> Cmd["src/command/index.ts"] Cmd --> Handlers["src/command/handlers/*.ts"] Entry --> Client["src/client/cosmoe.ts"] Sched["src/scheduler/index.ts"] --> Client Wcfg["wrangler.jsonc"] --> Entry Wcfg --> Sched ``` 图表来源 - [package.json](file://package.json#L12-L22) - [vitest.config.mts](file://vitest.config.mts#L1-L12) - [test/index.spec.ts](file://test/index.spec.ts#L1-L25) - [src/index.ts](file://src/index.ts#L1-L47) - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) 章节来源 - [package.json](file://package.json#L1-L24) - [vitest.config.mts](file://vitest.config.mts#L1-L12) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) ## 性能考虑 - 测试并发:在 Vitest 中合理拆分测试用例,避免阻塞;对异步任务使用 waitUntil 的等待策略。 - 外部依赖模拟:对 fetch、KV、Telegram API 进行模拟,减少真实网络开销。 - 基准测试:在本地与 Workers 环境分别测量命令处理与 API 请求的延迟,关注冷启动与热身差异。 - 压力测试:通过 Wrangler dev 的本地代理与日志观测,评估高并发下的稳定性与资源占用。 ## 故障排查指南 - 日志与可观测性:启用 wrangler.jsonc 中的 observability 开关,结合浏览器开发者工具 Network 面板查看请求与响应。 - 调试模式:使用 Wrangler dev 启动本地开发服务器,配合断点与日志定位问题。 - 环境隔离:确保测试与生产环境的 KV 绑定、cron 配置一致,避免因环境差异导致的失败。 - 常见问题: - 未等待 waitUntil:导致断言前异步任务未完成,需在测试中显式等待。 - KV 读写异常:检查命名空间绑定与键名格式,确保 JSON 序列化正确。 - Telegram API 返回异常:在处理器中捕获错误并记录堆栈,避免中断对话流程。 章节来源 - [wrangler.jsonc](file://wrangler.jsonc#L10-L12) - [test/index.spec.ts](file://test/index.spec.ts#L15-L16) ## 结论 通过 Vitest 与 @cloudflare/vitest-pool-workers 的组合,Cosmoe Bot 能够在本地 Workers 环境中高效地进行单元与集成测试。配合 fetch、KV、Telegram API 的模拟,可覆盖从命令到 API 的完整链路。建议持续完善测试矩阵,强化边界条件与错误场景,并结合 Wrangler 的可观测性能力进行性能与稳定性评估。 ## 附录 - 测试脚本:使用 npm/yarn 脚本运行测试,确保依赖安装与类型生成步骤正确。 - 类型生成:通过 wrangler types 生成运行时类型声明,保证测试与生产环境类型一致性。 章节来源 - [package.json](file://package.json#L5-L11) - [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L800)