
Playwright Test 注解与标签实战指南Annotations、Tags 与条件跳过机制【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright本文基于 Playwright 官方文档 test-annotations-js.md 展开系统讲解 Playwright Test 的标签tags与注解annotations体系从内置的skip/fail/fixme/slow注解到自定义 tag 的声明与--grep过滤再到组级条件跳过、beforeEach中的fixme以及运行时注解。读完本文你将能够用注解精确控制哪些测试运行、哪些不运行、失败是否符合预期并结合 testType.ts 等源码理解其底层实现。内置注解skip、fail、fixme、slowPlaywright 支持在测试报告test report中展示标签和注解。你可以随时添加自定义的 tag 和 annotation而 Playwright 本身就内置了几个最常用的注解test.skip将测试标记为无关Playwright 不会执行该测试。适用于测试在某些配置如某个浏览器、某个平台下不适用的场景。test.fail将测试标记为预期失败。Playwright 会照常执行该测试并验证它确实失败如果测试反而通过了Playwright 会报错提醒你。test.fixme同样将测试标记为失败状态但与fail不同Playwright 根本不会执行它。当测试执行很慢或直接崩溃时用fixme把它挂起来。test.slow将测试标记为慢测试并将其超时时间乘以三倍。注解可以加在单个测试上也可以加在测试组test.describe上。内置注解支持条件形式——传入条件参数truthy 时生效条件还可以依赖测试 fixtures如browserName、isMobile。同一个测试上可以叠加多个注解甚至可以来自不同的配置组合。从源码结构看这些注解本质上是类型受限的注解对象。test.ts 中定义了Modifier类型其type字段只允许slow | fixme | skip | fail四种取值与文档列出的四个内置注解一一对应。而测试的预期结果expected status也在 test.ts 中根据注解推导if (annotation.type skip || annotation.type fixme) this.expectedStatus skipped; else if (annotation.type fail this.expectedStatus ! skipped) this.expectedStatus failed;这解释了文档中skip 与 fixme 都不运行、fail 必须运行且必须失败的行为差异skip/fixme 使预期状态变为skipped而 fail 使预期状态变为failed若已被 skip/fixme 覆盖则保持 skipped。所有内置注解方法在 testType.ts 中统一注册到test对象上test.only wrapFunctionWithLocation(this._createTest.bind(this, only)); test.skip wrapFunctionWithLocation(this._modifier.bind(this, skip)); test.fixme wrapFunctionWithLocation(this._modifier.bind(this, fixme)); test.fail wrapFunctionWithLocation(this._modifier.bind(this, fail)); test.slow wrapFunctionWithLocation(this._modifier.bind(this, slow));skip、fixme、fail、slow共用同一个_modifier实现这也意味着它们在条件跳过等场景下具有完全一致的调用形态。聚焦测试test.only当你只想运行某个或某些测试时可以用test.only聚焦。项目中只要存在被聚焦的测试就只有这些测试会运行整个项目范围内的其他测试都会被跳过test.only(focus this test, async ({ page }) { // Run only focused tests in the entire project. });从源码看test.only在 testType.ts 中通过设置test._only true标记实现调度器据此过滤其余测试。跳过单个测试test.skip最简单的跳过方式test.skip(skip this test, async ({ page }) { // This test is not run });条件跳过单个测试在测试体内根据条件动态跳过。注意这里test.skip的第一个参数是条件而非测试标题test(skip this test, async ({ page, browserName }) { test.skip(browserName firefox, Still working on it); });_modifier的源码testType.ts揭示了它的三种调用位置在describe块中传函数 —— 注册为_modifiers加载阶段按条件求值在describe块中传条件非 function—— 条件为假时直接return不产生注解为真则推送静态注解在测试运行期间 —— 调用testInfo._modifier(...)对当前测试生效。这也解释了为什么条件形式可以依赖测试 fixtures在测试体内调用时_modifier直接作用于当前TestInfo实例。用 test.describe 分组测试用test.describe给测试一个逻辑名称也可以把 before/after 钩子的作用域限定在组内import { test, expect } from playwright/test; test.describe(two tests, () { test(one, async ({ page }) { // ... }); test(two, async ({ page }) { // ... }); });给测试打标签Tags当你想给测试打上fast/slow之类的标签然后在测试报告中按标签过滤或者只运行带某个标签的测试时tags 就有用武之地。给测试打标签有两种方式声明测试时通过 details 对象提供tag或者直接在测试标题中加入前缀的 token。注意tag 必须以符号开头import { test, expect } from playwright/test; test(test login page, { tag: fast, }, async ({ page }) { // ... }); test(test full report slow, async ({ page }) { // ... });也可以给整个组打标签或一次提供多个标签import { test, expect } from playwright/test; test.describe(group, { tag: report, }, () { test(test report header, async ({ page }) { // ... }); test(test full report, { tag: [slow, vrt], }, async ({ page }) { // ... }); });声明后可以用--grep命令行选项见 test-cli.md 的 all-options 一节只运行带特定标签的测试npx playwright test --grep fastPowerShell 下需要加引号npx playwright test --grep fast如果想反过来跳过带某标签的测试用--grep-invertnpx playwright test --grep-invert fast运行包含任一标签的测试逻辑ORnpx playwright test --grep fast|slow运行同时包含两个标签的测试逻辑AND借助正则前瞻npx playwright test --grep (?.*fast)(?.*slow)除了命令行还可以在配置文件中通过grep配置项TestConfig.grep和TestProject.grep对测试做过滤适合把只跑 fast 子集之类的策略固化到 playwright.config.ts 一类的配置文件里。从源码结构看标签与注解走的是同一套 details 校验管道testType.ts 中validateTestDetails校验后test.annotations.push(...validatedDetails.annotations)与test._tags.push(...validatedDetails.tags)分别落位组级 tags 则存在Suite._tagstest.ts 中注释明确区分了显式声明的 tags与标题中解析出的 tags。--grep的匹配对象正是由两部分标题与 tags 组合而成的检索路径Suite._collectGrepTitlePathtest.ts因此标题里的slow与 details 里的tag: slow对--grep而言等价。自定义注解Annotations当你需要比 tag 更有料的信息时可以使用注解。注解由type和description组成可以在 reporter API 中读取。Playwright 内置的 HTML 报告会展示所有注解唯独不展示type以_开头的注解——这是一个留给内部的命名空间例如框架自身使用的元数据注解。例如用一个 issue URL 注解测试import { test, expect } from playwright/test; test(test login page, { annotation: { type: issue, description: https://github.com/microsoft/playwright/issues/23180, }, }, async ({ page }) { // ... });同样可以注解整个组或一次提供多个注解import { test, expect } from playwright/test; test.describe(report tests, { annotation: { type: category, description: report }, }, () { test(test report header, async ({ page }) { // ... }); test(test full report, { annotation: [ { type: issue, description: https://github.com/microsoft/playwright/issues/23180 }, { type: performance, description: very slow test! }, ], }, async ({ page }) { // ... }); });条件跳过一组测试给test.skip/test.fixme传回调函数即可实现组级条件跳过例如让一组测试只在 Chromium 上运行test.describe(chromium only, () { test.skip(({ browserName }) browserName ! chromium, Chromium only!); test.beforeAll(async () { // This hook is only run in Chromium. }); test(test 1, async ({ page }) { // This test is only run in Chromium. }); test(test 2, async ({ page }) { // This test is only run in Chromium. }); });对照_modifier的源码testType.ts在 describe 块中传入 function 时它被压入suite._modifiers等运行阶段按 fixture 参数求值后再决定是否给组内测试打上 skip/fixme 注解。在 beforeEach 钩子中使用 fixme如果连beforeEach钩子本身都不想让它执行比如页面在移动端还没适配可以把注解放进钩子内部test.beforeEach(async ({ page, isMobile }) { test.fixme(isMobile, Settings page does not work in mobile yet); await page.goto(http://localhost:3000/settings); }); test(user profile, async ({ page }) { await page.getByText(My Profile).click(); // ... });条件成立时当前测试被标记为 fixme预期 skipped钩子中test.fixme之后的语句不再有意义地影响结果。这对应_modifier的第三种调用形态运行期间经testInfo._modifier(type, location, ...)作用于当前测试testType.ts。运行时注解test.info().annotations测试已经在运行时也可以动态追加注解写入test.info().annotationstest(example test, async ({ page, browser }) { test.info().annotations.push({ type: browser version, description: browser.version(), }); // ... });这些注解会随TestInfo一起进入 reporter 数据在 reporterTestRun.ts、teleEmitter.ts 等报告中随测试结果一并序列化因此 HTML 报告、JSON 报告、JUnit 报告等都能拿到它们。小结注解体系如何落到源码把文档行为与源码对应起来可以得到一张清晰的映射表文档中的能力源码位置与机制test.skip/fixme/fail/slow四内置注解testType.ts 统一经_modifier注册test.only聚焦testType.ts 置test._only trueskip/fixme/fail的标题式调用test.skip(title, body)testType.ts 转发到_createTest并在 L120-L123 追加带location的注解预期状态推导skip/fixme → skippedfail → failedtest.ts组级条件注解回调形式suite._modifierstest.ts 定义testType.ts 写入自定义 tags/annotations 的声明校验validateTestDetailstestType.ts分别落入TestCase.annotations、Suite._staticAnnotations与各级_tags这套机制让 Playwright Test 的选择运行哪些测试完全数据化静态注解在文件加载期就写入Suite._staticAnnotations/TestCase.annotations动态注解在运行期经TestInfo落位最终统一呈现在测试报告中——这也是注解annotation与标签tag虽然入口相似、语义却分层的根本原因tag 服务于过滤--grep、grep配置annotation 服务于表达reporter API、HTML 报告展示。【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考