测试与调试
本文引用的文件
- vitest.config.mts
- test/index.spec.ts
- test/env.d.ts
- test/tsconfig.json
- package.json
- tsconfig.json
- src/index.ts
- src/command/index.ts
- src/client/cosmoe.ts
- src/scheduler/index.ts
- src/command/handlers/start.ts
- src/command/handlers/login.ts
- src/command/handlers/events.ts
- wrangler.jsonc
- worker-configuration.d.ts
目录
- 简介
- 项目结构
- 核心组件
- 架构总览
- 详细组件分析
- 依赖关系分析
- 性能考虑
- 故障排查指南
- 结论
- 附录
简介
本文件面向 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 配置、包脚本与类型生成
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
- test/index.spec.ts
- src/index.ts
- src/command/index.ts
- src/scheduler/index.ts
- src/client/cosmoe.ts
- wrangler.jsonc
- worker-configuration.d.ts
- package.json
- tsconfig.json
章节来源
- vitest.config.mts
- test/index.spec.ts
- src/index.ts
- src/command/index.ts
- src/scheduler/index.ts
- src/client/cosmoe.ts
- wrangler.jsonc
- worker-configuration.d.ts
- package.json
- tsconfig.json
核心组件
- Worker 入口与命令系统:负责初始化 Bot、注册命令与回调、设置菜单,并通过 webhook 回调接入 Cloudflare 运行时。
- 命令处理器:提供 start、login(交互式对话)、events、event*、book*、history、cancel_*、callbackQuery 等处理流程。
- API 客户端:封装对 Cosmoe API 的请求,包括认证、事件查询、用户资料、预订、优惠券、支付单号更新、变更/转移/取消等。
- 调度任务:定时拉取新活动并向已注册用户发送通知,同时维护最新活动 ID。
章节来源
- src/index.ts
- src/command/index.ts
- src/client/cosmoe.ts
- src/scheduler/index.ts
架构总览
下图展示测试视角下的关键交互:Vitest 使用 @cloudflare/vitest-pool-workers 在本地启动 Workers 环境,通过 cloudflare:test 的执行上下文与 SELF 发起请求,从而覆盖 Worker 入口与调度器。
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 : "创建执行上下文<br/>等待 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
- src/index.ts
- src/scheduler/index.ts
详细组件分析
单元测试与 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
- test/index.spec.ts
- test/env.d.ts
- test/tsconfig.json
Worker 入口与命令系统测试
- 入口测试要点:构造 Request,创建空执行上下文,调用 worker.fetch 并断言响应;使用 waitOnExecutionContext 等待后台任务。
- 命令注册:通过 setupCommands 安装对话插件与各命令处理器,测试应覆盖命令匹配、正则路由与回调查询。
环境变量:Bot 令牌、KV 绑定、Bot 信息等由 wrangler.jsonc 提供,测试需在相同环境下运行。
flowchart TD
Start(["开始:构造请求"]) --> Ctx["创建执行上下文"]
Ctx --> Fetch["调用 worker.fetch"]
Fetch --> Wait["等待 waitUntil 完成"]
Wait --> Assert["断言响应内容/状态"]
Assert --> End(["结束"])
图表来源
- test/index.spec.ts
- src/index.ts
章节来源
- src/index.ts
- src/command/index.ts
- wrangler.jsonc
API 客户端测试策略
- 网络请求模拟:使用 fetch 的模拟实现,控制返回码与数据,覆盖成功、鉴权缺失、参数校验失败等分支。
- 错误场景:模拟网络异常、服务端错误、鉴权失败、参数不合法等。
- 异步操作:对所有异步方法进行超时与重试策略测试,确保 Promise 正常收敛。
数据契约:基于接口定义(如 ApiResponse、Event、UserProfile 等)编写结构化断言。
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()
}
图表来源
章节来源
命令处理器测试
- start 命令:验证消息回复内容与格式。
- login 交互:模拟用户输入用户名/密码,断言登录结果与 KV 写入。
events 命令:断言事件列表构建与 Markdown 格式输出。
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
- src/client/cosmoe.ts
章节来源
- src/command/handlers/start.ts
- src/command/handlers/login.ts
- src/command/handlers/events.ts
调度任务测试
- 场景设计:准备不同时间点的事件列表,验证“新增事件”过滤逻辑与 KV 最大 ID 更新。
- 测试数据:使用 COSMOE_STORAGE 存储 latestEventId,COSMOE_CREDENTIALS 存储用户凭证,模拟多用户通知。
环境隔离:通过 Wrangler 配置的 KV 绑定与 cron 触发器,在测试中以 scheduled 事件驱动。
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
- src/client/cosmoe.ts
章节来源
- src/scheduler/index.ts
- wrangler.jsonc
依赖关系分析
- 测试依赖:Vitest + @cloudflare/vitest-pool-workers;cloudflare:test 提供执行上下文与 SELF。
- 应用依赖:grammy 与 @grammyjs/conversations 实现对话与命令;KV 命名空间用于会话与凭证存储。
运行时依赖:Wrangler 提供 KV 绑定、cron 触发器与可观测性开关。
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
- vitest.config.mts
- test/index.spec.ts
- src/index.ts
- src/command/index.ts
- src/scheduler/index.ts
- wrangler.jsonc
章节来源
- package.json
- vitest.config.mts
- wrangler.jsonc
性能考虑
- 测试并发:在 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
- test/index.spec.ts
结论
通过 Vitest 与 @cloudflare/vitest-pool-workers 的组合,Cosmoe Bot 能够在本地 Workers 环境中高效地进行单元与集成测试。配合 fetch、KV、Telegram API 的模拟,可覆盖从命令到 API 的完整链路。建议持续完善测试矩阵,强化边界条件与错误场景,并结合 Wrangler 的可观测性能力进行性能与稳定性评估。
附录
- 测试脚本:使用 npm/yarn 脚本运行测试,确保依赖安装与类型生成步骤正确。
- 类型生成:通过 wrangler types 生成运行时类型声明,保证测试与生产环境类型一致性。
章节来源
- package.json
- worker-configuration.d.ts