想去哪里?

首页 页面 关于 页面 项目 页面 简历 页面 技术 页面 随笔 页面 联系 页面 隐私政策 页面 Terminal Spike 隐私政策 页面 用 Astro 构建文档与职业个人网站 技术 通过 tmux、Mosh、Termius 与 Tailscale 随处使用 Codex 技术 用 Langfuse 观察 Codex 的 MCP 工具调用 技术 产品应用中的本地化 技术 把 MCP 作为安全的 AI 集成边界 技术 用 Zod、OpenAPI 与 Swagger 维护 API 契约 技术 用 pg-boss 运行持久后台任务 技术 通过真实知识工作流理解 pgvector 与 RAG 技术 Pi Edge:让 Pi 待在 Obsidian 笔记旁 技术 为真实排序任务设计拖放交互 技术 Prisma 与 PostgreSQL:产品状态的事实来源 技术 把 Ralph Loop 当作计划队列 技术 用 React Router 组织全栈产品工作流 技术 把 shadcn 风格组件变成自己的产品系统 技术 用表格与编辑器承载密集业务操作 技术 Terminal Spike:原生 Android 终端 技术 在 Linux 上用 fcitx 输入带声调的拼音 技术 在 Linux 上配置 DEFT Pro 轨迹球 技术 在 KOReader 上使用 Pocket 稍后读 技术 为 Vercel AI SDK 设置明确的工具边界 技术 垂直切片架构与 dependency-cruiser 技术 用 Vitest 与 Playwright 测试产品工作流 技术 我的随处工作流:Herdr、code-server、Obsidian 与 Pi Edge 技术 Zod 不只是校验 技术 《卡拉马佐夫兄弟》是我看过最好的小说 随笔 基督徒口述1960劳改历史 随笔 圣经中的“道”与言语 随笔 我们爱,因为神先爱我们,而不是空洞的“自爱” 随笔 妈妈,让我来承担爸爸的过错吧 随笔 我与神的故事 随笔 世界远离上帝,接近中国 随笔 “爱的五种语言”和内外向,只存在于语言中 随笔 人格类型不存在,你在世界而非概念中生活 随笔 危险的词语:为什么心理学是不可能的 随笔 2000 年,一个深圳打工者的故事 随笔 阿联酋Ras al Khaimah见闻录 随笔 沙甸:1975 年的一场冲突 随笔 关于中国的纪录片 随笔
← 技术/工程实践

用 Vitest 与 Playwright 测试产品工作流

将流程测试分为快速服务检查,以及少量真正重要的浏览器路径。

我不想要只能证明函数工作的测试集,而想保护那些一旦坏了就会造成损害的工作流。

这不意味着每条规则都需要浏览器测试。浏览器有价值,但更慢、更脆弱。可以直接用 Vitest 测产品规则时,我通常从那里开始。

例如没有标题的请求不能提交:

test("cannot submit an empty request", async () => {
  await expectSubmitRequest({ title: "" }).rejects.toThrow("Title is required");
});

这是简化测试,展示规则应在哪一层验证。检查空标题无效,不必打开浏览器;服务测试更快,也更贴近问题。

Playwright 回答另一个问题:用户能否完成整个路径,打开页面、填写表单、提交、跟随跳转并看到新状态?

它能发现连接问题:表单缺少 name、跳转错误、loader 错误、权限问题,以及服务测试看不到的界面状态。

浏览器测试应聚焦关键路径:创建最常创建的对象、编辑常用对象、提交或批准流程、看到证明成功的状态,再覆盖一个重要权限或失败路径。

我曾因为 E2E 更贴近产品,就把太多测试放进去,结果变成缓慢清单。失败时不清楚究竟是规则、选择器、种子数据还是浏览器不稳定。

更合理的分工是 Vitest 覆盖规则、服务、校验、格式和小型集成边界;Playwright 覆盖少数确实需要全栈参与的用户旅程。

截图和 trace 对 CI 失败尤其有帮助,因为没有人在看浏览器。但私有截图应保持私有,公开写作宁愿用小演示应用,或不放截图。

测试边界也需要维护。服务太薄,服务测试证明不了多少;UI 拥有太多逻辑,浏览器就成为唯一测试方式。这通常说明代码边界需要改进,而非应该增加更多浏览器覆盖。

通过测试不代表产品绝对正确,只代表某些预期仍成立。价值在于选择与用户风险相符的预期。

服务测试:无效输入不能提交
服务测试:有效提交改变状态
服务测试:无权限用户被拒绝
浏览器测试:用户创建、提交,并看到已提交状态

这不是穷尽所有情况,而是实用起点:保护规则和路径,同时不把每种细小变化都变成完整浏览器测试。