自动化测试
了解 TanStarter 的测试覆盖范围与执行方式
TanStarter 使用 Vitest 验证逻辑与服务边界,使用 Playwright 验证浏览器流程,并为 Stripe、Creem、Waffo 提供真实沙盒支付测试。以下命令均在应用项目根目录执行。
测试覆盖
| 测试类型 | 验证内容 | 命令 |
|---|---|---|
| 单元测试 | 认证、支付 Provider、Webhook、权限边界、数据库迁移、内容链接与 AI 响应解析 | pnpm test |
| 本地 E2E | 中英文页面、注册登录、管理员权限、资料与密码修改、API Key、文件上传下载、路由边界和 Clef 交互 | pnpm e2e |
| Worker 冒烟测试 | 本地生产构建的 SSR、Hydration、认证重定向、健康检查和测试接口隔离 | pnpm e2e:production |
| 支付沙盒 | 托管结账、真实 Webhook 与本地 D1 支付状态 | pnpm e2e:stripe / creem / waffo |
单元测试使用 Mock 隔离外部服务;本地 E2E 使用真实的本地认证、D1 和 R2。邮件投递、Google OAuth 与真实 AI 输出需另行验证。
执行测试
首次安装依赖和浏览器:
pnpm install
pnpm e2e:install日常修改后,运行代码检查与浏览器测试:
pnpm check # 只读 Biome 检查 + 全部单元测试
pnpm e2e模板升级或发布前,运行完整本地验证:
pnpm verify:upgrade # check → build → e2e → e2e:production也可以只运行相关测试:
pnpm test tests/unit/payment
pnpm test:watch
pnpm e2e -- tests/e2e/specs/auth.spec.ts
pnpm e2e:ui浏览器测试会自行启动服务、初始化隔离数据并应用迁移,请保持测试端口空闲。e2e:production 测试本地构建后的 Worker,不会部署;verify:upgrade 不包含支付沙盒测试。
支付自动化测试
测试了什么
支付单元测试验证结账参数、签名、事件处理、乱序与重复投递、重试、退款和订单归属,防止旧订单或其他用户的支付状态被误用。
真实沙盒测试则完成托管结账,等待服务商 Webhook,并检查本地 D1 记录:
| Provider | 沙盒覆盖 |
|---|---|
| Stripe | 月付、年付、终身版、零金额订单、拒付、门户换套餐、取消订阅与全额退款 |
| Creem | 月付、年付、终身版、拒付与到期取消 |
| Waffo | 月付、年付、终身版,以及支付事件不重复创建或覆盖订阅状态 |
Stripe 通过 invoice.paid 确认已支付;Waffo 区分支付事件与订阅生命周期事件。续费和部分异常路径由单元测试覆盖,沙盒套件不覆盖所有服务商生命周期。
怎么执行
将当前服务商的测试密钥和价格/产品 ID 放入 .env.e2e,或通过 shell 导出。三套测试均自动启动隔离 Worker 和 D1,无需另开开发服务。
| Provider | 默认端口 | 额外准备 |
|---|---|---|
| Stripe | 3019 | 安装 Stripe CLI;Runner 自动监听并注入临时 Webhook 密钥 |
| Creem | 3021 | 启动 HTTPS 隧道,注册 Test Mode Webhook 并配置签名密钥 |
| Waffo | 3018 | 启动 HTTPS 隧道,注册 Test Mode Webhook 并保留签名请求头 |
pnpm e2e:stripe
pnpm e2e:creem
pnpm e2e:waffo
# 只运行一个场景
pnpm e2e:stripe -- --grep "monthly subscription"使用同一沙盒账号下的密钥和产品。支付 Runner 不读取开发者的 .dev.vars;Creem/Waffo 不会自动创建隧道或注册 Webhook。详细配置见项目中的 tests/e2e/<provider>/README.md。
维护与排查
测试位于 tests/unit/ 和 tests/e2e/,用户流程记录在 tests/e2e/TEST-CATALOG.md。功能变化时更新相关测试,优先验证请求、权限与持久化结果,避免依赖精确文案或样式。
失败时先查看终端输出和 test-results/;支付一直待确认时,检查 Webhook、签名与隧道连接。保留的 Trace 可通过 pnpm exec playwright show-trace <trace.zip> 查看。
下一步
最后更新于
