☰
Dillinger 项目 Web 应用测试指南:Playwright E2E 与深度审计策略实战
2026/9/27 21:45:51 网站建设 项目流程
  • 前端
  • 开发工具

【免费下载链接】dillinger

The last Markdown editor, ever.

项目地址:https://gitcode.com/gh_mirrors/di/dillinger
点击查看免费下载

本文以仓库内 .agent/skills/webapp-testing/SKILL.md 为骨架,结合 Dillinger(Next.js 14 在线 Markdown 编辑器)仓库中的真实 E2E 测试、Playwright 配置与 API 路由测试展开。读完本文,你将掌握一套可落地的 Web 应用测试方法论:从深度审计清单、E2E 优先级排序、Playwright 配置调优,到 API 边界测试、测试组织与 CI 集成,并能在 Dillinger 仓库中找到每一处对应的实现证据直接对照。

1. 测试工具箱:运行时脚本与依赖准备

SKILL 文档为自动化浏览器测试提供了一组开箱即用的运行时脚本,核心入口是scripts/playwright_runner.py:

脚本用途用法
scripts/playwright_runner.py基础浏览器测试python scripts/playwright_runner.py https://example.com
(同上,带截图)截图辅助python scripts/playwright_runner.py <url> --screenshot
(同上,无障碍检查)可访问性审计python scripts/playwright_runner.py <url> --a11y

脚本依赖 Python 侧安装 Playwright 及 Chromium:

pip install playwright && playwright install chromium

需要说明的是,这一通用脚本属于技能文档中的通用运行器方案;Dillinger 仓库实际的 E2E 运行体系是@playwright/test驱动。在 package.json 中可以找到完整命令链:

"test": "npm run test:unit && npm run test:e2e", "test:unit": "vitest run", "test:e2e": "npm run build && playwright test", "test:e2e:headed": "npm run build && playwright test --headed", "verify": "npm run lint && npm run typecheck && npm run test:unit && npm run test:e2e"

其中test:e2e先执行npm run build再跑 Playwright,verify则把 lint、类型检查、单元测试与 E2E 全链路串起来,与 SKILL 文档中"CI 流水线先装依赖、再装浏览器、再跑测试"的思想一致。开发依赖中的@playwright/test(^1.58.2)即仓库 E2E 的实际载体。

2. 深度审计方法:先发现,后系统化测试

SKILL 文档强调 Web 应用测试的第一原则是"发现并测试一切,不留任何未测试路由"。审计的第一步是发现(Discovery):

目标如何发现
路由(Routes)扫描app/、pages/、router 文件
API 端点Grep 搜索 HTTP 方法(GET/POST/PUT/DELETE)
组件(Components)定位组件目录
功能(Features)阅读文档

在 Dillinger 仓库中,这套发现路径可以精确落地:

  • 路由:Next.js App Router 结构集中在 app 目录,包括编辑器主页 app/page.tsx、导出、导入、OAuth 回调等 API 路由(如 app/api/export/html/route.ts);
  • 组件:位于 components 下的editor/、preview/、sidebar/、modals/、navbar/等目录;
  • API 端点:app/api/下按github/、dropbox/、google-drive/、onedrive/、bitbucket/等云服务组织的 route.ts 文件,对应各云存储集成;
  • 功能:docs 目录下的设计文档与迁移计划。

发现之后进入系统化测试三步法:

  1. Map(映射)——列出所有路由与 API;
  2. Scan(扫描)——验证它们都能正常响应;
  3. Test(测试)——覆盖关键路径。

Dillinger 仓库的测试布局正是这三步的产物:tests/routes/覆盖 API 路由,tests/e2e/覆盖关键用户路径,tests/components/、tests/hooks/、tests/lib/、tests/store/覆盖单元层面。

3. Web 测试金字塔

SKILL 文档用金字塔模型说明 Web 应用的测试投入比例:

/\ E2E (少量) / \ 关键用户流程 /----\ / \ Integration (适量) /--------\ API、数据流 / \ /------------\ Component (大量) 单个 UI 部件

要点:E2E 测试昂贵,只应用于关键路径;大量测试应落在金字塔底部的组件与单元层。Dillinger 仓库的 tests 目录正是这一模型的实证:e2e/仅 5 个 spec 文件(smoke、editor、import-export、logobar、settings-sidebar),而组件、hooks、lib、store 的单元测试文件更多更细,金字塔底部明显更厚。

4. E2E 测试原则

4.1 测什么:按优先级排序

优先级测试内容
1快乐路径(Happy path)用户流程
2认证流程(Authentication flows)
3关键业务操作(Critical business actions)
4错误处理(Error handling)

在 Dillinger 的 tests/e2e/smoke.spec.ts 中可以看到典型的快乐路径覆盖:加载编辑器外壳 → 断言标题、侧边栏切换按钮、#preview预览区、字数与字符数统计 → 隐藏/显示预览 → 打开设置弹窗 → 验证 Night Mode 开关可见。这正是"先测外壳稳定,再深入细节"的冒烟策略。

4.2 E2E 最佳实践

实践原因
使用>// 摘自 tests/e2e/settings-sidebar.spec.ts:确定性状态种子注入 function seedLocalStorage( documents = seededDocuments, current = seededDocuments[0], profile = defaultProfile ) { return (args) => { if (window.localStorage.getItem("files")) return; window.localStorage.setItem("files", JSON.stringify(args.documents)); window.localStorage.setItem("currentDocument", JSON.stringify(args.current)); window.localStorage.setItem("profileV3", JSON.stringify(args.profile)); }; }

这一模式是"清理状态、测试独立"的实战范本:不依赖外部数据库或网络,用种子数据把每个用例固定在同一初始状态,从根上消除顺序依赖导致的 flaky。

5. Playwright 原理与配置实践

5.1 核心概念

概念用途
Page Object Model封装页面逻辑,提升复用与可读性
Fixtures可复用的测试前置设置
Assertions内置自动等待(auto-wait)
Trace Viewer调试失败用例,回放操作轨迹

5.2 配置推荐

配置项推荐值
RetriesCI 上设为 2
Traceon-first-retry
Screenshotson-failure
Videoretain-on-failure

Dillinger 仓库的 playwright.config.ts 与推荐值几乎逐条对应,可作标准配置模板:

export default defineConfig({ testDir: "./tests/e2e", fullyParallel: true, reporter: "list", timeout: 45_000, expect: { timeout: 5_000 }, use: { baseURL, trace: "on-first-retry", screenshot: "only-on-failure", video: "retain-on-failure", }, projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }], webServer: { command: `npx next dev -H 127.0.0.1 -p ${port}`, url: baseURL, reuseExistingServer: !process.env.CI, timeout: 180_000, }, });

要点解读:

  • trace: "on-first-retry":仅在重试时录制 trace,兼顾调试能力与性能开销,对应推荐值;video: "retain-on-failure"只在失败时保留视频,是 CI 排障的关键证据;
  • fullyParallel: true:文件级并行,对应 SKILL 文档中"Per file 是 Playwright 默认并行策略";
  • webServer:自动启动next dev(监听127.0.0.1:3005)并等待就绪,reuseExistingServer: !process.env.CI在本地复用已启动的 dev server、在 CI 中强制全新启动——配置注释还记录了关键经验:"使用 dev 模式,因为 production build 存在预先存在的预渲染错误";
  • timeout: 45_000/expect.timeout: 5_000:为慢速断言(如异步 Markdown 渲染)预留充足等待,对应"避免硬编码等待、使用自动等待"的原则。事实上 tests/e2e/editor.spec.ts 中针对异步预览渲染的断言特意放宽到{ timeout: 10_000 }。

6. 视觉测试

6.1 何时使用

场景价值
设计系统(Design system)高
营销页面(Marketing pages)高
组件库(Component library)中
动态内容(Dynamic content)较低

6.2 策略

  • Baseline screenshots(基线截图)
  • Compare on changes(变更时对比)
  • Review visual diffs(人工审阅视觉差异)
  • Update intentional changes(确认有意变更后更新基线)

7. API 测试原则

7.1 覆盖维度

维度测试点
状态码200、400、404、500
响应结构匹配 schema
错误消息用户友好
边界情况空值、大体积、特殊字符

7.2 Dillinger 中的 API 测试实证

仓库在 tests/routes 下用 Vitest(@vitest-environment node)直接调用 Next.js 路由处理函数做纯 Node 环境测试,tests/routes/export-html.route.test.ts 是教科书式示例:

it("rejects missing markdown", async () => { const response = await exportHtml( new Request("http://localhost/api/export/html", { method: "POST", body: JSON.stringify({}), }) as never ); expect(response.status).toBe(400); }); it("renders styled and plain HTML variants with stable filenames", async () => { // styled: true → 响应体包含 <style> // styled: false → 响应体不含 <style> expect(styledResponse.headers.get("Content-Disposition")).toContain( 'filename="Exported.html"' ); expect(await styledResponse.text()).toContain("<style>"); expect(await plainResponse.text()).not.toContain("<style>"); });

该测试完整覆盖了状态码(缺参返回 400)、响应结构(HTML 是否含<style>样式块)、响应头(Content-Disposition文件名稳定性)三类维度,与 SKILL 文档中"状态码 + 响应结构 + 错误消息 + 边界情况"的 API 测试原则一一对应。同类测试还包括export-markdown、export-pdf、github.route、import-html-to-markdown、upload-image等路由。

8. 测试组织结构与命名约定

8.1 文件结构

SKILL 文档推荐的标准结构:

tests/ ├── e2e/ # 完整用户流程 ├── integration/ # API、数据 ├── component/ # UI 单元 └── fixtures/ # 共享数据

Dillinger 仓库的 tests 目录与之同构(integration 层以routes/目录呈现):

tests/ ├── e2e/ # 完整用户流程(Playwright) ├── routes/ # API 路由测试(Vitest) ├── components/ # UI 单元测试 ├── hooks/ # 自定义 hooks 测试 ├── lib/ # 核心库测试(markdown、export、import 等) └── store/ # Zustand 状态管理测试

这种"E2E 只测关键路径、API 与单元测试铺底"的布局,正是金字塔模型的落地形态。

8.2 命名约定

模式示例
基于功能(Feature-based)login.spec.ts
描述性(Descriptive)user-can-checkout.spec.ts

Dillinger 的 E2E 文件命名两者兼取:smoke.spec.ts(功能型)、settings-sidebar.spec.ts(功能型)、import-export.spec.ts(功能型);而测试用例名则全部采用描述性句式,如"switches between documents and updates the editor and preview"、"deletes a document after confirmation"、"hides word count when disabled in settings"(见 tests/e2e/editor.spec.ts),失败时可读性极佳。

9. CI 集成

9.1 流水线步骤

  1. 安装依赖(Install dependencies)
  2. 安装浏览器(Install browsers)
  3. 运行测试(Run tests)
  4. 上传产物(Upload artifacts:traces、screenshots)

9.2 并行化策略

策略适用场景
按文件并行(Per file)Playwright 默认策略
分片(Sharding)大型测试套件
多 Worker多浏览器并行

Dillinger 的 playwright.config.ts 通过fullyParallel: true启用文件级并行;package.json的verify脚本把 lint → typecheck → 单元测试 → E2E 串成一条可放入 CI 的完整流水线。结合配置中的trace/screenshot/video三件套,CI 失败时能自动保留 trace、截图与视频作为可下载的诊断产物,与文档推荐的流水线第 4 步"上传 artifacts"完全吻合。

10. 反模式清单

❌ 不要✅ 要
测试实现细节(Test implementation)测试行为(Test behavior)
硬编码等待(Hardcode waits)使用自动等待(Use auto-wait)
跳过清理(Skip cleanup)隔离测试(Isolate tests)
忽视 flaky 测试(Ignore flaky tests)修复根因(Fix root cause)

在 Dillinger 仓库中可以找到每条反模式的正面对照:

  • 测行为而非实现:smoke.spec.ts用getByRole断言"Toggle sidebar""Hide preview""Open settings"等用户可见交互,从不触碰组件内部状态;
  • 自动等待替代硬编码:所有断言依赖 Playwright 内置 auto-wait,异步渲染场景通过显式timeout参数而非page.waitForTimeout处理;
  • 清理与隔离:addInitScript种子注入 + "仅空 localStorage 才注入"的守卫,保证用例间互不污染;
  • 修复根因:playwright.config.ts注释记录了对 dev/prod 模式差异的真实根因排查结论,而非简单绕开问题。

结语

Remember: E2E tests are expensive. Use them for critical paths only.

Dillinger 仓库把 SKILL 文档中的每一条原则都落成了可运行、可复现的代码:fullyParallel的并行配置、on-first-retry的 trace、addInitScript的确定性状态种子、getByRole的行为级断言,以及 Vitest 直调路由函数的 API 测试。无论你是要给 Dillinger 增加新的 E2E 用例(参考 tests/e2e 现有 spec 的模式),还是为下一个 Web 应用搭建测试体系(以 playwright.config.ts 为起点),这套"深度审计 → 金字塔分层 → 关键路径 E2E → 边界化 API 测试 → CI 产物留证"的流程都值得直接照搬。

  • 前端
  • 开发工具

【免费下载链接】dillinger

The last Markdown editor, ever.

项目地址:https://gitcode.com/gh_mirrors/di/dillinger
点击查看免费下载
上一篇:告别投稿焦虑!Elsevier投稿追踪工具让你实时掌握审稿进度
下一篇:终极Godot资源解包指南:3分钟掌握.pck文件提取技巧

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询