首页
/ Playwright 测试配置(use)完全指南:Emulation、Network 与 Recording 选项的深度解析

Playwright 测试配置(use)完全指南:Emulation、Network 与 Recording 选项的深度解析

2026-09-06 19:23:37作者:谭伦延

导读

本文以 Playwright 测试运行器的核心配置块 use 为切入点,系统梳理如何在 playwright.config.ts 中统一声明浏览器上下文(BrowserContext)的仿真、网络与录制行为,并逐层讲解 baseURL、设备仿真、代理、TLS、trace/video 录制模式、显式上下文创建以及全局/项目/测试三级作用域的继承与覆盖机制。阅读完成后,你将掌握在单个文件中声明、按 project 细分、按 test.use() 精准覆盖的完整配置技巧,并能理解这些选项在 Playwright 源码中是如何被解析为浏览器上下文参数的。

use 配置块的本质:一组内建 fixture 选项

@playwright/test 的入口实现中,use 中的每一项配置都被实现为一个带 option: true 标记的 fixture。例如:

  • browserNamepackages/playwright/src/index.ts 中定义,默认读取 defaultBrowserType'chromium'
  • viewport 默认值为 { width: 1280, height: 720 }
  • colorScheme 默认 'light'locale 默认 'en-US'
  • headless 默认取 launchOptions.headless ?? true,即默认无头运行。

因此,你写在 use: {} 里的每一项,本质上都是为这些 fixture 赋初值,再由运行器在你每个测试运行时装配到 browsercontextpage 这些内建 fixture 之中。理解这一点,就能理解为什么“有的选项作用于浏览器实例、有的作用于上下文”,以及为什么它们可以按作用域层层覆盖。

基础选项:baseURL 与 storageState

最常见的两个顶层选项是页面导航基准地址与登录态注入:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // Base URL to use in actions like `await page.goto('/')`.
    baseURL: 'http://localhost:3000',

    // Populates context with given storage state.
    storageState: 'state.json',
  },
});
Option Description
baseURL 配置上下文中所有页面使用的基准 URL,允许仅凭路径完成导航,例如 page.goto('/settings')
storageState 用给定的存储状态填充上下文,是快速实现登录态复用(authentication)的关键手段。

补充细节:

  • baseURL 也接受环境变量 PLAYWRIGHT_TEST_BASE_URL 的注入(见 packages/playwright/src/index.ts),这一特性对 CI 中切换不同测试环境非常实用。
  • storageState 参数既可以传相对配置文件所在目录的文件路径,也可以直接传包含 cookiesorigins 的对象字面量。
  • 关于基于 storageState 的完整登录态方案,可阅读 认证指南

Emulation Options:从设备到时区的全链路仿真

Playwright 允许你仿真真实的移动端或平板设备,也可以针对所有测试或单个测试仿真 geolocationlocaletimezone,并通过 permissions 授予通知等权限、通过 colorScheme 切换配色主题。项目级设备矩阵可参考 test projects 指南 与 Emulation 指南

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // Emulates `'prefers-colors-scheme'` media feature.
    colorScheme: 'dark',

    // Context geolocation.
    geolocation: { longitude: 12.492507, latitude: 41.889938 },

    // Emulates the user locale.
    locale: 'en-GB',

    // Grants specified permissions to the browser context.
    permissions: ['geolocation'],

    // Emulates the user timezone.
    timezoneId: 'Europe/Paris',

    // Viewport used for all pages in the context.
    viewport: { width: 1280, height: 720 },
  },
});
Option Description
colorScheme 仿真 prefers-colors-scheme 媒体特性,支持 'light''dark',默认 'light'
geolocation 设置上下文的地理位置
locale 仿真的用户语言,例如 en-GBde-DE 等,默认 'en-US'
permissions 授予上下文所有页面的一组权限
timezoneId 改变上下文的时区
viewport 上下文所有页面使用的视口尺寸,默认 { width: 1280, height: 720 }

从源码看,这些配置最终会被逐一搬入 BrowserContextOptions:在 packages/playwright/src/index.ts_combinedContextOptions fixture 中,colorSchemegeolocationlocaletimezoneIdviewport 等字段会被非空判断后写入上下文参数对象;随后在 runBeforeCreateBrowserContext 钩子里,只有在用户显式传入的参数不包含该 key 时,测试选项才会被合并进去——这保证了运行时显式传入的上下文选项优先于 use 中的声明

值得注意的补充选项:

  • deviceScaleFactor(DPR,默认 1)、hasTouchisMobileuserAgentserviceWorkersreducedMotioncontrastforcedColors 同样可以放进 use;这些上下文级选项在 packages/playwright/src/index.ts 中都有对应的默认值兜底。
  • permissions 常见取值包括 'geolocation''notifications''camera''microphone' 等浏览器权限名,配置后上下文中所有页面默认已获得授权。

Network Options:下载、请求头、认证、TLS 与代理

可用网络配置如下:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // Whether to automatically download all the attachments.
    acceptDownloads: false,

    // An object containing additional HTTP headers to be sent with every request.
    extraHTTPHeaders: {
      'X-My-Header': 'value',
    },

    // Credentials for HTTP authentication.
    httpCredentials: {
      username: 'user',
      password: 'pass',
    },

    // Whether to ignore HTTPS errors during navigation.
    ignoreHTTPSErrors: true,

    // Whether to emulate network being offline.
    offline: true,

    // Proxy settings used for all pages in the test.
    proxy: {
      server: 'http://myproxy.com:3128',
      bypass: 'localhost',
    },
  },
});
Option Description
acceptDownloads 是否自动接受下载,默认 true。下载相关细节见 downloads 指南
extraHTTPHeaders 随每次请求发送的附加 HTTP 头对象,所有头值必须是字符串。
httpCredentials HTTP 认证凭据。
ignoreHTTPSErrors 导航过程中是否忽略 HTTPS 错误,默认 false
offline 是否仿真网络离线,默认 false
proxy 测试中所有页面使用的代理设置

补充说明:

  • acceptDownloadsextraHTTPHeadershttpCredentialsignoreHTTPSErrorsofflineproxy 等选项在 packages/playwright/src/index.ts 中同样声明了各自的默认值(如 acceptDownloads ?? trueoffline ?? false),说明它们是“面向测试运行器的封装”,最终都会流入 BrowserContextOptions
  • proxyserver 为必填项,bypass 是可选的分号分隔的主机列表,表示这些地址不走代理;配置为 '*' 表示全部绕过。
  • 除代理、认证外,Playwright 还支持 clientCertificates:为特定 origin 提供 TLS 客户端证书(certPath/keyPath、或 pfxPath,可选 passphrase),见 packages/playwright/types/test.d.ts。证书相关路径会以配置文件所在目录为基准做解析。

注:模拟网络请求时你其实无需做任何配置。只要为浏览器上下文注册自定义 Route 即可完成对网络的 mock。完整的 mock 方案见 network mocking 指南

Recording Options:截图、Trace 与视频

Playwright 可以自动捕获截图、录制视频以及生成 trace。默认三者均关闭,可通过在配置文件中设置 screenshotvideotrace 选项开启。trace、截图和视频文件都会输出到测试输出目录(通常是 test-results)。

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // Capture screenshot after each test failure.
    screenshot: 'only-on-failure',

    // Record trace only when retrying a test for the first time.
    trace: 'on-first-retry',

    // Record video only when retrying a test for the first time.
    video: 'on-first-retry'
  },
});
Option Description
screenshot 捕获测试的截图,可选 'off''on''only-on-failure'
trace Playwright 在测试运行期间产生 trace,之后可通过 Trace Viewer 回放详细的执行信息。可选 'off''on''retain-on-failure''on-first-retry' 等模式(完整列表见下文)。
video 为测试录制视频,模式集合与 trace 一致。

Trace 模式速查

trace 选项支持多种模式,其差异体现在哪些运行会被录制以及测试结束后哪些录制结果会被保留。一次测试的首次运行称为 “first run”,由重试引起的后续运行称为 “retries”。

Mode Records a trace on Keeps the trace when
'off' never
'on' every run always
'retain-on-failure' every run that run failed
'retain-on-first-failure' first run only the first run failed
'retain-on-failure-and-retries' every run that run failed, or it is a retry
'on-first-retry' first retry only always
'on-all-retries' every retry always

下表展示了在配置 retries: 2 的前提下,几个常见场景分别会保留哪些 trace:

Mode Passes on first run Fails, then passes on retry Fails on every run
'off'
'on' first run first run + retry all three runs
'retain-on-failure' first run all three runs
'retain-on-first-failure' first run first run
'retain-on-failure-and-retries' first run + retry all three runs
'on-first-retry' first retry first retry
'on-all-retries' first retry both retries

模式名的完整集合可从类型定义 packages/playwright/types/test.d.ts 中确认:'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure' | 'retain-on-failure-and-retries'。在 worker 端 trace 逻辑中可以看到这些模式的实际判定逻辑,例如 'on-first-retry' 要求 testInfo.retry === 1(即只在第一次重试时录制),'retain-on-failure' 在测试失败时保留录制。需要注意:

  • 早期版本中的 'retry-with-trace' 已标记为废弃,会被归一化为 'on-first-retry'(见 packages/playwright/src/worker/testTracing.ts)。
  • trace 还支持对象形态 { mode: 'on', snapshots: true, screenshots: true, sources: true },用于精细化控制是否录制 DOM/ARIA 快照、页面截图与源码映射。

视频模式速查

video 选项支持与 trace 完全相同的一组模式,录制与保留遵循同样的规则。

Mode Records a video on Keeps the video when
'off' never
'on' every run always
'retain-on-failure' every run that run failed
'retain-on-first-failure' first run only the first run failed
'retain-on-failure-and-retries' every run that run failed, or it is a retry
'on-first-retry' first retry only always
'on-all-retries' every retry always

同样假设 retries: 2,各场景保留的视频如下:

Mode Passes on first run Fails, then passes on retry Fails on every run
'off'
'on' first run first run + retry all three runs
'retain-on-failure' first run all three runs
'retain-on-first-failure' first run first run
'retain-on-failure-and-retries' first run + retry all three runs
'on-first-retry' first retry first retry
'on-all-retries' first retry both retries

从实现上看,视频的“是否录制”与“是否保留”被拆成了两个独立函数 shouldCaptureVideoshouldPreserveVideo(见 packages/playwright/src/index.ts):录制决策发生在上下文创建之前(例如 'on-first-retry' 需要 testInfo.retry === 1),而保留决策则发生在测试结束、拿到 testInfo.status 之后。保留的视频会以 test-{status}-{index}.webm 命名并保存到测试输出目录。对象形态的 video: { mode: 'retain-on-failure', size: { width, height } } 允许你进一步指定录制分辨率,'retry-with-video' 同样已被废弃并归一化为 'on-first-retry'

截图模式与失败时行为

  • screenshot 的类型在 packages/playwright/types/test.d.ts 中定义为 'off' | 'on' | 'only-on-failure' | 'on-first-failure',支持 on-first-failure(仅首次运行失败时截图)。
  • 截图同样支持对象形态,例如 screenshot: { mode: 'on', fullPage: true, omitBackground: true },可透传 fullPageomitBackgroundpage.screenshot()
  • 失败时测试错误上下文(error-context)也会被收集,便于结合 trace 一起排障,见 ArtifactsRecorder 的实现

其他选项:超时、浏览器选择与选择器约定

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // Maximum time each action such as `click()` can take. Defaults to 0 (no limit).
    actionTimeout: 0,

    // Name of the browser that runs tests. For example `chromium`, `firefox`, `webkit`.
    browserName: 'chromium',

    // Toggles bypassing Content-Security-Policy.
    bypassCSP: true,

    // Channel to use, for example "chrome", "chrome-beta", "msedge", "msedge-beta".
    channel: 'chrome',

    // Run browser in headless mode.
    headless: false,

    // Change the default data-testid attribute.
    testIdAttribute: 'pw-test-id',
  },
});
Option Description
actionTimeout 每个 Playwright action(如 click())的超时毫秒数,默认 0(无限制)。超时机制的完整讲解见 test timeouts 指南。
browserName 运行测试的浏览器名,默认 'chromium',可选 chromiumfirefoxwebkit
bypassCSP 是否绕过页面 Content-Security-Policy,当 CSP 包含生产域名、阻碍测试注入时很有用,默认 false
channel 使用的浏览器渠道(channel),例如 "chrome""chrome-beta""msedge""msedge-beta"。更多浏览器与渠道细节见 browsers 指南
headless 是否以无头模式运行浏览器(运行时不展示浏览器窗口),默认 true
testIdAttribute 改变 Playwright 定位器默认使用的 data-testid 属性,默认值即 data-testid

源码补充:

  • 传入非法的 browserName 会直接抛出 Unexpected browserName "xxx" 错误,合法的三取值在 packages/playwright/src/index.ts 中校验。
  • actionTimeoutnavigationTimeout 会分别在上下文创建阶段被设置到 playwright._defaultContextTimeout / _defaultContextNavigationTimeout,作为页面级默认超时(见 packages/playwright/src/index.ts)。
  • testIdAttribute 底层调用的是 selectors.setTestIdAttribute(testIdAttribute)(见 packages/playwright/src/index.ts),即不仅影响 getByTestId(),还同步影响 page.locator('data-testid=...') 这一类内置引擎。
  • 与此同级的还有 navigationTimeoutreuseContextconnectOptionsserviceWorkers 等运行期选项;defaultBrowserTypescreenshottracevideolaunchOptions 属于 worker 级配置,整个 worker 进程内共享。

更多浏览器与上下文选项:launchOptions / contextOptions / connectOptions

任何被 BrowserType.launch 接受的启动选项、被 Browser.newContext 接受的上下文选项、或被 BrowserType.connect 接受的连接选项,都可以分别放入 use 下的 launchOptionscontextOptionsconnectOptions

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    launchOptions: {
      slowMo: 50,
    },
  },
});

这里 slowMo: 50 让每个操作之间人为停顿 50ms,适合演示与调试。不过,绝大多数常用项(如 headlessviewport)已经直接暴露在 use 顶层,正如上文的基础选项、仿真选项与网络选项所示,只有在使用非内置的“长尾”参数时才需要借助这三个分组。相应地:

  • launchOptions 默认 {}(worker 级);真实启动参数会在 packages/playwright/src/index.ts 中合并 headlesschanneltracesDir 后传给浏览器进程;
  • connectOptions 允许不本地启动浏览器而是连接一个已运行的远程端点,若设置了 PLAYWRIGHT_TEST_BASE_URL 类似的环境变量或 PW_TEST_CONNECT_WS_ENDPOINT,连接信息会自动注入(见 packages/playwright/src/index.ts);
  • contextOptions 提供了把任意上下文参数“整体透传”的逃生通道,其内容与 _combinedContextOptions 展开出的具名字段会做浅合并。

显式创建上下文时的选项继承与优先级

在一个测试或 hook 运行期间,凡是经由测试运行器使用的 Playwright 实例创建的浏览器上下文,都会自动继承 use 段中的上下文选项。这包括:

  • 使用内建 browser fixture 调用 browser.newContext() 创建的上下文;
  • 通过另行 launch 的浏览器创建的上下文;
  • 使用 BrowserType.launchPersistentContext 创建的持久化上下文;
  • 直接 import playwright-core 且解析到同一实例时创建的上下文。

并且,显式传入的上下文选项始终优先于 use 声明。背后的机制是 packages/playwright/src/index.tsrunBeforeCreateBrowserContext 的合并逻辑——它只为参数对象里“还没有的 key”补充默认值。

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    userAgent: 'some custom ua',
    viewport: { width: 100, height: 100 },
  },
});

下面这个测试可以验证 use 选项确实被应用到了新创建的上下文上:

test('should inherit use options on context when using built-in browser fixture', async ({
  browser,
}) => {
  const context = await browser.newContext();
  const page = await context.newPage();
  expect(await page.evaluate(() => navigator.userAgent)).toBe('some custom ua');
  expect(await page.evaluate(() => window.innerWidth)).toBe(100);
  await context.close();
});

Configuration Scopes:全局、项目、文件与单测的覆盖链

Playwright 允许你按全局、按项目、按测试文件、按 describe 块甚至按单个测试来逐级配置。以 locale 为例,可以先在全局 use 中设置默认值:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    locale: 'en-GB'
  },
});

然后在某个项目内覆盖为德语(此处还借助了 devices['Desktop Chrome'] 预置的设备描述符):

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        locale: 'de-DE',
      },
    },
  ],
});

devices 描述符本质上就是一个展开的选项对象(可对照 deviceDescriptors.ts 查看),因此“合并项目专属仿真”与“展开某个设备定义”可以自然组合。

也可以对整个测试文件覆盖——用 test.use() 传入选项即可。例如让特定文件里的测试以法语运行:

import { test, expect } from '@playwright/test';

test.use({ locale: 'fr-FR' });

test('example', async ({ page }) => {
  // ...
});

同样的写法也适用于 describe 块内,让块内测试使用法语:

import { test, expect } from '@playwright/test';

test.describe('french language block', () => {

  test.use({ locale: 'fr-FR' });

  test('example', async ({ page }) => {
    // ...
  });
});

优先级关系总结为:单个测试的 test.use() > 文件/describe 内的 test.use() > project 的 use > config 顶层 use。因为 use 选项本质是带作用域的 fixture option,该机制与 fixtures.ts 中实现的 fixture 覆盖链完全一致——内层声明会覆盖外层同名选项。

重置某个选项:回到 config 或彻底置空

如果文件级/describe 级 test.use() 已经把某个选项改掉,你仍可以在更内层把它“重置”回配置文件定义的值。考虑如下 config,它设置了 baseURL

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    baseURL: 'https://playwright.dev',
  },
});

随后在测试文件中先为整个文件配置新的 baseURL,再在某个 describe 块里退回到 config 定义的值:

import { test } from '@playwright/test';

// Configure baseURL for this file.
test.use({ baseURL: 'https://playwright.dev/docs/intro' });

test('check intro contents', async ({ page }) => {
  // This test will use "https://playwright.dev/docs/intro" base url as defined above.
});

test.describe(() => {
  // Reset the value to a config-defined one.
  test.use({ baseURL: undefined });

  test('can navigate to intro from the home page', async ({ page }) => {
    // This test will use "https://playwright.dev" base url as defined in the config.
  });
});

这里的关键技巧是:test.use({ baseURL: undefined }) 会把该文件级设置移除,从而回退到上一层(config 顶层)的值。如果你希望把值彻底清空为 undefined(即连 config 中的默认值也不使用),则需使用长格式的 fixture 语法:

import { test } from '@playwright/test';

// Completely unset baseURL for this file.
test.use({
  baseURL: [async ({}, use) => use(undefined), { scope: 'test' }],
});

test('no base url', async ({ page }) => {
  // This test will not have a base url.
});

这段长格式声明覆盖了整个测试文件的 baseURL fixture,使其始终产出 undefined,从而完全绕过 config 中的默认 baseURL。由此可以推导出更通用的规则:凡是形如 option: [async ({}, use) => use(value), { scope: 'test' }] 的长格式写法,都能在文件或 describe 粒度直接接管某个 fixture 选项的默认来源。

典型配置模板:把知识组合进一个真实项目

参考仓库中 examples/github-apiexamples/todomvc 的写法,一个同时覆盖“仿真 + 网络 + 录制 + 多项目”的 use 段落通常长这样:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  retries: 2,
  reporter: [['html', { open: 'never' }]],
  use: {
    baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    locale: 'en-GB',
    timezoneId: 'Europe/Paris',
    viewport: { width: 1280, height: 720 },
    httpCredentials: { username: 'user', password: 'pass' },
    launchOptions: { slowMo: 0 },
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'mobile-safari', use: { ...devices['iPhone 13'] } },
  ],
});
  • 顶层的 retries: 2use 中的 trace: 'on-first-retry' 组合,可精确实现“只对第一次重试录 trace”——这与上文 trace 模式表中 retries: 2 的推演场景一一对应;
  • baseURL 交给环境变量,让 CI 与本地共用同一份配置;
  • 不同浏览器/设备用 projects 表达,配合 docs/src/test-projects.md 可进一步做设备矩阵与并行分片。

小结

use 配置块是 Playwright 测试项目中承上启下的枢纽:向上它承接 config 顶层与 project 的定义,向下它把 BrowserType.launch / Browser.newContext / BrowserType.connect 三套 API 的参数统一收口。从 源码实现 可以看到,它依赖一套带 option: true 的 fixture 体系完成声明式默认值管理,又通过 _combinedContextOptionsrunBeforeCreateBrowserContext 实现“显式优先、use 兜底”的上下文合并语义;录制类的 trace/video 选项则在 “shouldCapture”(何时录)与 “shouldPreserve”(录了留不留)两阶段分别决策。配合全局 → 项目 → 文件 → describe → 单测的覆盖链与“赋 undefined 回退 / 长格式彻底置空”两种重置手法,你可以在几乎不写额外代码的前提下,把整套浏览器行为声明得清晰、稳定且易于在多个项目与 CI 环境间复用。

延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐