Positron Playwright E2E 测试文件结构完全指南:从目录组织到用例编写的官方规范

发布时间:2026/10/5 2:11:22
Positron Playwright E2E 测试文件结构完全指南:从目录组织到用例编写的官方规范 开发工具代码编辑器数据科学【免费下载链接】positronPositron, a next-generation data science IDE项目地址https://gitcode.com/gh_mirrors/po/positron点击查看免费下载本篇技术指南以 Positron 官方测试规范文档 .claude/skills/author-e2e-tests/references/test-structure.md 为核心骨架系统讲解 Positron下一代数据科学 IDEPlaywright E2E 测试文件的组织方式、完整模板、Hook 作用域、标签与注解机制、test.step使用原则以及并行测试注意事项。读完本文你将能够按照 Positron 的既定约定编写结构正确、可靠、可直接进入 CI 的 E2E 测试文件并避免最常见的踩坑点。一、测试文件存放位置按功能模块组织Positron 的 E2E 测试按功能特性feature组织在test/e2e/tests/目录下每个功能模块一个子目录test/e2e/tests/ ├── _test.setup.ts # 核心 setup - 每个文件都必须从这里导入 ├── _global.setup.ts # 全局 setup整个测试运行只执行一次 ├── console/ # Console/REPL 测试 ├──>/*--------------------------------------------------------------------------------------------- * Copyright (C) CURRENT YEAR Posit Software, PBC. All rights reserved. * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. *--------------------------------------------------------------------------------------------*/ import { join } from path; import { test, expect, tags } from ../_test.setup; // REQUIRED: Unique suite ID for app isolation test.use({ suiteId: __filename }); test.describe(Feature Name - Subsection, { tag: [tags.WEB, tags.WIN, tags.CRITICAL, tags.FEATURE_TAG] }, () { // Worker-scoped setup runs once per file. For settings known up front, apply // them pre-launch instead of here (see Custom Test Setup Files in // references/fixtures.md) so theres no reload. // Test-scoped setup (runs before each test) test.beforeEach(async ({ app }) { await app.workbench.layouts.enterLayout(fullSizedPanel); }); // Test-scoped cleanup (runs after each test) test.afterEach(async ({ app, hotKeys }) { await app.workbench.dataExplorer.filters.clearAll(); await hotKeys.closeAllEditors(); }); // Worker-scoped cleanup (runs after all tests in file) test.afterAll(async ({ cleanup }) { await cleanup.removeTestFiles([generated-file.txt]); }); // Test with auto-started interpreter test(Test with Python, async ({ app, python }) { // Python interpreter automatically started before this runs await app.workbench.console.executeCode(Python, print(hello)); await app.workbench.console.waitForConsoleContents(hello); }); // Test with manual session management test(Test with manual session, async ({ app, sessions }) { await sessions.start(python); // ... test logic }); // Test with per-test tags test(Specific platform test, { tag: [tags.WIN], // Only on Windows annotation: [{ type: issue, description: https://github.com/posit-dev/positron/issues/1234 }] }, async ({ app, r }) { // R-specific test }); });模板中CURRENT YEAR需替换为当前年份仓库内现有文件的版权头格式可见 test/e2e/tests/example.test.ts。两条强制要求Mandatory Requirements规范文档明确强调模板中有两行是每个文件都必须有的必须从../_test.setup导入而非playwright/testimport { test, expect, tags } from ../_test.setup。自定义_test.setup提供了 Positron 的全部自定义 fixturesapp、python、r、sessions等直接用原始 Playwright 导入会导致 fixture 报错。必须设置test.use({ suiteId: __filename })这是应用隔离的关键。缺少它测试可能错误地共享 app 实例日志无法按测试文件组织beforeAll/afterAll的行为也会异常。导入原则是只用文件实际用到的东西test和tags总是导入expect仅在编写原始断言时导入——如果所有断言都通过 POM 方法完成就不要导入expect否则未使用的导入会触发 lint 失败。这一要求同样被写入技能文档 .claude/skills/author-e2e-tests/SKILL.md 的 MANDATORY REQUIREMENTS 一节并在 .claude/skills/author-e2e-tests/references/common-mistakes.md 的 #1、#2 两条中解释了缺失时的破坏后果#1 错误的导入来源——错误写法import { test, expect } from playwright/test正确写法import { test, expect, tags } from ../_test.setup#2 缺失 suiteId——必须写test.use({ suiteId: __filename })否则 app 实例共享方式可能出错、日志无法按测试文件组织、beforeAll/afterAll行为异常。真实仓库中的落地示例以 test/e2e/tests/console/console-python.test.ts 为例可以看到上述模板的真实落地形态import { test as base, tags } from ../_test.setup; const test base.extend{}, {}({ beforeApp: [ async ({ settingsFile }, use) { await settingsFile.append({ python.useBundledIpykernel: false, kernelSupervisor.logLevel: trace, }); await use(); }, { scope: worker } ], }); test.use({ suiteId: __filename }); test.describe(Console Pane: Python, { tag: [tags.WEB, tags.CONSOLE, tags.WIN] }, () { test(Python - Verify console commands are queued during execution, async function ({ app, sessions, python }) { await app.workbench.sessions.clearConsoleAllSessions(); await app.workbench.console.pasteCodeToConsole(123 123); // do not send to console await app.workbench.console.executeCode(Python, 456 456); await app.workbench.console.waitForConsoleContents(912, { expectedCount: 1, timeout: 10000 }); await app.workbench.console.waitForConsoleContents(123 123, { expectedCount: 1, timeout: 10000 }); await app.workbench.console.waitForConsoleContents(246, { expectedCount: 0, timeout: 5000 }); }); // ... });该文件还示范了beforeAppworker fixture 的用法在应用启动前通过settingsFile.append(...)预写设置如关闭 bundled ipykernel、将 supervisor 日志级别提到 trace 以诊断 issue 15060 相关的内核卡死问题从而避免启动后的窗口重载。三、Hook 作用域worker 级 vs test 级由于app是worker 级worker-scopedfixture每个测试文件共享同一个 app 实例因此 Hook 的作用域语义如下Hook作用域运行频次典型用途beforeAll/afterAllworker每个测试文件一次而非全局一次worker 级 fixtures如settings、cleanupbeforeEach/afterEachtest每个测试一次UI 状态重置如hotKeys.closeAllEditors()、layouts.enterLayout(...)模板中两者均已给出上下文示例beforeEach里调用app.workbench.layouts.enterLayout(fullSizedPanel)进入统一布局afterEach里通过app.workbench.dataExplorer.filters.clearAll()与hotKeys.closeAllEditors()复位 UI 状态afterAll里用cleanup.removeTestFiles([generated-file.txt])清理测试生成的临时文件。关于每个文件一次还有一处实现细节test/e2e/tests/_test.setup.ts 中的注释说明——Playwright 的 worker 理论上可处理多个 spec但 Positron 利用suiteId确保每个 suite 获得一个新的 worker进而获得全新的 app 实例从而保证这些before/afterAll钩子对每个 spec 都会执行日志也能按 spec 隔离setSpecName将 spec 名存入全局变量suite 结束后重命名日志目录。四、测试标签Test Tags平台过滤与特性标注每个test.describe都必须通过tag数组打标签并可在需要时在单条测试上覆盖/追加。标签的来源与分类规范文档明确指出可用标签是FeatureTags测试覆盖的功能与PlatformTags测试运行平台两个枚举以 test/e2e/tests/../infra/test-runner/test-tags.ts 中的实际定义为准而不是文档里的硬编码清单。从源码看该文件将标签按角色拆成两个枚举再合并为统一的TestTags对象与类型让测试统一使用tags.CONSOLE、tags.WINFeatureTags特性标签如:console、:data-explorer、:notebooks、:plots、:variables、:critical、:performance等在默认的 Linux/Electron 通道运行是唯一可被自动测试变更标签推导选中的标签见 scripts/derive-test-change-tags.mjsPlatformTags平台/通道选择器如:web、:win、:cross-browser、:remote-ssh、:workbench等由作者在 PR 中手动添加各自对应一个专门的 CI job不会从测试文件变更自动推导唯一的例外是新增的tags.WIN/tags.WEB会通过 scripts/lib/pr-tags-lib.sh 的scan_added_platform_tags扫描启用:win/:web。平台标签的默认行为与扩展没有平台标签的测试只会在 Linux/Electron 上运行。要让测试在更多平台运行需要显式添加tags.WEB在 Web 浏览器模式下运行tags.WIN在 Windows 上运行tags.CROSS_BROWSER跨 Chrome、Firefox、WebKit、Edge 多浏览器运行提示变更需考虑跨浏览器兼容性。标签的层级覆盖规则// Describe 级标签作用于块内所有测试单条测试的 tag 覆盖/追加 test.describe(Console, { tag: [tags.WEB, tags.WIN, tags.CRITICAL, tags.CONSOLE] }, () { ... });模板中同时展示了两种用法describe级统一打标以及单条测试级test(Specific platform test, { tag: [tags.WIN], ... })只针对 Windows 的特化覆盖。自定义 Feature 标签的维护约定源码注释还透露了新增特性标签的约定若新标签对应某个源码目录需将该目录加入 .github/workflows/test-tag-paths-map.json使触碰该目录的 PR 能被自动打标scripts/check-test-tag-map.sh 负责防止两份清单漂移。五、测试注解Test Annotations关联 Issue 与标记已知 flakyPositron 使用 Playwright 标准的annotation数组作为test(...)的第二个参数与tag并列传入关联 Issue{ type: issue, description: url }把测试与对应缺陷/需求单绑定例如模板中的annotation: [{ type: issue, description: https://github.com/posit-dev/positron/issues/1234 }]标记已知 flaky{ type: fixme, description: ... }标注已知不稳定但暂不阻塞的测试。六、使用 test.step避免双重包装规范文档的核心原则大多数 POM 动作/校验方法内部已经用test.step自包装因此在 POM 调用外面再套一层test.step只会产生冗余的嵌套步骤让报告更臃肿而非更清晰。正确的使用方式是把test.step保留给还不是 POM 调用的原始 Playwright 序列。判断依据见 .claude/skills/author-e2e-tests/references/common-mistakes.md #9不确定某个方法是否自包装时去 test/e2e/pages/ 下 grep 该方法体内是否有test.step(。文档特别指出并非所有 POM 方法都自包装——例如console.waitForReady和plots.waitForNoPlots就没有。七、并行测试注意事项同文件共享 app 且不得依赖执行顺序同一文件内的测试共享一个 worker 级 app 实例因此它们之间绝不能依赖执行顺序。规范文档给出了两条硬性纪律在afterEach中重置 UI 状态对应 .claude/skills/author-e2e-tests/references/common-mistakes.md #8一个测试的残留状态不得泄漏到下一个测试——状态泄漏是 E2E 测试 flake 最常见的来源之一。典型写法test.afterEach(async ({ hotKeys }) { await hotKeys.closeAllEditors(); });若测试会编辑工作区文件在afterAll中恢复所有 worker 共享同一个工作区目录因此只能点名恢复本测试动过的文件绝不能做仓库级整体重置否则会清掉并行运行的其他 spec 正在写入的内容test.afterAll(async ({ cleanup }) { // 测试编辑过的已跟踪文件 await cleanup.restoreFiles([join(workspaces, chinook-db-py, chinook-sqlite.py)]); // 测试新建的文件 await cleanup.removeTestFiles([output.txt]); });八、配套参考fixture 与常见错误速览本规范文档与技能体系中的其他参考文档互为补充全部位于 .claude/skills/author-e2e-tests/references/fixtures 速查.claude/skills/author-e2e-tests/references/fixtures.mdapp访问app.workbench.*POM、page直接 Playwright 页面、python/r测试前自动启动解释器并等待就绪、sessions手动会话管理await sessions.start(python)、executeCode、openFile、hotKeys、settings、cleanup等权威清单与类型在 test/e2e/tests/_test.setup.ts 的TestFixtures/WorkerFixtures接口中。常见错误清单.claude/skills/author-e2e-tests/references/common-mistakes.md17 条 Positron 特有陷阱覆盖导入来源、suiteId、平台标签、interpreter 不会跨测试保留、settings 的 worker 作用域、15 秒默认超时expect.timeout见playwright.config.ts、toPass与自重试断言的区别、固定等待page.waitForTimeout等。测试运行命令来自技能文档编写完成后可按如下方式运行与调试# 运行单个测试文件 npx playwright test test-name.test.ts --project e2e-electron # 运行某个分类下的全部测试 npx playwright test test/e2e/tests/category/ # 按标签筛选 npx playwright test --grep :critical # 有头模式可看到浏览器 npx playwright test --headed # 调试模式单步执行 npx playwright test --debug # 查看测试报告 npx playwright show-report九、总结提交前的结构自查清单将规范文档与配套参考合并一个结构正确的测试文件应满足从../_test.setup或所在目录的_test.setup导入而非playwright/test开头必有test.use({ suiteId: __filename })describe带有合适的标签平台标签 特性标签已知的设置值在启动前通过beforeApp/settingsFile写入而非测试中途settings.set()触发重载afterEach完成 UI 状态重置afterAll清理/恢复工作区文件POM 方法名从 test/e2e/pages/ 源码复制而非臆造POM 调用不套冗余test.step原始 Playwright 序列才用test.step包装测试相互独立不依赖执行顺序每个断言验证不同的东西。赞分享开发工具代码编辑器数据科学【免费下载链接】positronPositron, a next-generation data science IDE项目地址https://gitcode.com/gh_mirrors/po/positron点击查看免费下载相关推荐Positron Playwright E2E 测试编写指南从测试结构、Fixtures 到防 Flaky 实战Positron Playwright E2E 测试编写指南从测试结构、Fixtures 到防 Flaky 实战 本指南以 Positron 仓库内置的 au开发工具代码编辑器数据科学PostHog Playwright E2E 测试编写全指南从规划到零 flaky 的实战工作流PostHog Playwright E2E 测试编写全指南从规划到零 flaky 的实战工作流 导读 本文围绕 PostHog 仓库中的 playwrigh数据分析后端前端数据可视化大数据Handsontable 测试编写实战指南Jest 单元测试与 Playwright E2E 的分层规范Handsontable 测试编写实战指南Jest 单元测试与 Playwright E2E 的分层规范 本文以 Handsontable monorepo前端UI组件上一篇NS-USBLoader终极指南一站式解决Switch文件传输、RCM注入和文件管理难题下一篇3步解锁QQ音乐加密格式Mac用户的终极音乐自由指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考