测试与调试.md 14 KB

测试与调试

本文引用的文件

  • 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

目录

  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 配置、包脚本与类型生成

    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()
    }
    

图表来源

  • src/client/cosmoe.ts

章节来源

  • src/client/cosmoe.ts

命令处理器测试

  • 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