Skip to content

Playwright Test 超时

Playwright Test 为不同任务提供了多种可配置的超时。合理设置超时可以帮助你更快发现卡住的测试,也可以避免 CI 任务在异常情况下长时间占用资源。

超时类型默认值说明配置方式单独覆盖方式
测试超时30_000 ms每个测试的最大执行时间timeout: 60_000test.setTimeout(120_000)
Expect 断言超时5_000 ms每个自动重试断言的最大等待时间expect: { timeout: 10_000 }expect(locator).toBeVisible({ timeout: 10_000 })

Playwright Test 会对每个测试施加超时限制,默认是 30 秒。这个时间包含测试函数本身、fixture 的 setup 阶段,以及 beforeEach 钩子的执行时间。

当测试超过限制时,通常会看到类似下面的错误:

example.spec.ts:3:1 › basic test ===========================
Timeout of 30000ms exceeded.

测试函数结束之后,fixture 的 teardown 阶段和 afterEach 钩子会使用一段独立的超时时间,默认值与测试超时相同。

beforeAllafterAll 钩子也会使用相同的超时值,不过它们不会与某个具体测试共享执行时间。

可以在 playwright.config.ts 中为整个测试项目设置默认测试超时:

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
timeout: 120_000,
});

对应 API:testConfig.timeout

如果某个测试确实比较慢,可以在测试内部单独设置超时:

example.spec.ts
import { test, expect } from '@playwright/test';
test('slow test', async ({ page }) => {
test.slow(); // 简单地把默认超时扩展为 3 倍
// ...
});
test('very slow test', async ({ page }) => {
test.setTimeout(120_000);
// ...
});

对应 API:test.setTimeout()test.slow()

你可以通过 testInfo.setTimeout()beforeEach 中动态修改当前测试的超时时间。

example.spec.ts
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }, testInfo) => {
// 将运行此钩子的所有测试的超时时间增加 30 秒。
testInfo.setTimeout(testInfo.timeout + 30_000);
});

对应 API:testInfo.setTimeout()

修改 beforeAll / afterAll 钩子的超时

Section titled “修改 beforeAll / afterAll 钩子的超时”

beforeAllafterAll 钩子拥有独立的超时,默认与测试超时相同。可以在钩子内部调用 test.setTimeout() 或通过 testInfo.setTimeout() 调整它。

example.spec.ts
import { test, expect } from '@playwright/test';
test.beforeAll(async () => {
// 设置当前钩子的超时。
test.setTimeout(60_000);
});

对应 API:testInfo.setTimeout()

类似 expect(locator).toHaveText() 这样的自动重试断言,有自己独立的超时,默认是 5 秒。断言超时与测试超时不是同一个概念。

断言超时时,可能会看到类似下面的错误:

example.spec.ts:3:1 › basic test ===========================
Error: expect(received).toHaveText(expected)
Expected string: "my text"
Received string: ""
Call log:
- expect.toHaveText with timeout 5000ms
- waiting for "locator('button')"

可以通过 expect.timeout 为所有断言设置默认超时时间:

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
timeout: 10_000,
},
});

对应 API:testConfig.expect

也可以直接给某个断言传入 timeout 参数:

example.spec.ts
import { test, expect } from '@playwright/test';
test('example', async ({ page }) => {
await expect(locator).toHaveText('hello', { timeout: 10_000 });
});

Playwright Test 支持为整个测试运行过程设置全局超时。它主要用于防止在整体流程异常时持续消耗资源。

全局超时默认没有开启。你可以根据 CI 的实际情况设置一个合理值,例如 1 小时。

全局超时触发时,可能会看到类似下面的输出:

Running 1000 tests using 10 workers
514 skipped
486 passed
Timed out waiting 3600s for the entire test run

在配置文件中设置全局超时:

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalTimeout: 3_600_000,
});

对应 API:testConfig.globalTimeout

下面这些是测试运行器预先配置的较底层超时。一般情况下不需要修改它们。

超时类型默认值说明配置方式单独覆盖方式
动作超时无默认超时每个动作的超时,例如点击、填写等use: { actionTimeout: 10_000 }locator.click({ timeout: 10_000 })
导航超时无默认超时每次导航动作的超时use: { navigationTimeout: 30_000 }page.goto('/', { timeout: 30_000 })
全局超时无默认超时整个测试运行过程的超时globalTimeout: 3_600_000
beforeAll / afterAll 超时30_000 ms钩子的超时在钩子中设置test.setTimeout(60_000)
Fixture 超时无默认超时单个 fixture 的超时在 fixture 配置中设置{ scope: 'test', timeout: 30_000 }

在配置文件中设置动作和导航超时

Section titled “在配置文件中设置动作和导航超时”

可以在 use 选项中设置动作超时和导航超时:

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
actionTimeout: 10 * 1000,
navigationTimeout: 30 * 1000,
},
});

对应 API:testOptions.actionTimeouttestOptions.navigationTimeout

可以在调用具体动作时传入 timeout 参数:

example.spec.ts
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev', { timeout: 30_000 });
await page.getByText('Get Started').click({ timeout: 10_000 });
});

默认情况下,fixture 会与测试共享超时时间。不过对于比较慢的 fixture,尤其是 worker 级别的 fixture,为它设置独立超时会更方便。

这样可以让整体测试超时保持较小,同时给慢 fixture 留出更充足的初始化时间。

example.spec.ts
import { test as base, expect } from '@playwright/test';
const test = base.extend<{ slowFixture: string }>({
slowFixture: [async ({}, use) => {
// ... 执行较慢的操作 ...
await use('hello');
}, { timeout: 60_000 }],
});
test('example test', async ({ slowFixture }) => {
// ...
});

对应 API:test.extend()

  • 优先区分“测试超时”和“断言超时”:测试超时控制整个测试,断言超时只控制单个自动重试断言。
  • 不要简单地把所有超时都调得很大。超时过长会掩盖真正的问题,并拖慢 CI 反馈。
  • 对确实慢的测试或 fixture,优先做局部配置,而不是全局放宽限制。
  • 如果测试经常因为等待元素失败,应优先检查定位器、页面状态、网络响应和测试数据,而不是只增加动作超时。
-
0:000:00