并行执行、分片 Sharding 与重试 Retries
本教程共 59 篇 · 第 44 篇 · 更新于 2026-08-04 · 约 12 分钟阅读
44. 并行执行、分片 Sharding 与重试 Retries
本节目标:学完能控制并行 worker 数量、把测试切到多台机器提速,并配置失败自动重试,让大套件既快又抗抖动。
测试一多,跑一遍动辄十几分钟。这一章讲怎么把时间砍下来:本地用多进程并行,CI 上用分片摊到多台机器,再配上重试消化偶发抖动。
并行的基本模型
Playwright 默认就并行——它会起若干个 worker 进程(操作系统级进程),同时跑不同的测试文件。文件之间并行,文件内的测试默认按顺序。
Noteworker(工作进程)是独立运行的 OS 进程,每个都自带浏览器、环境互相隔离。测试文件会被轮流塞进空闲的 worker 里跑。
控制 worker 数量
想少开几个、或多开几个,用 --workers:
npx playwright test --workers 4
配置里写更灵活,比如本地放开、CI 上收一档:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
workers: process.env.CI ? 2 : undefined, // 本地用默认,CI 上限定 2
});
workers 还能写成百分比,按机器 CPU 核数按比例开:
npx playwright test --workers=50%
只想彻底串行,设成 1:
npx playwright test --workers=1
Warningworker 之间无法通信。测试若依赖另一个测试留下的副作用,并行一开就会随机失败。保持每条测试独立,是并行的前提。
文件内也并行
默认同文件内顺序跑。要并行,用 describe.configure 或配置 fullyParallel:
// 写在测试文件顶部,只影响这个文件
import { test } from '@playwright/test';
test.describe.configure({ mode: 'parallel' });
// playwright.config.ts:一次让所有文件都并行
import { defineConfig } from '@playwright/test';
export default defineConfig({ fullyParallel: true });
分片:摊到多台机器
worker 再多用也受单机 CPU 限制。分片(Sharding)把测试切成几份,每份丢到一台机器上并行跑,整体提速接近线性。
npx playwright test --shard=1/4
npx playwright test --shard=2/4
npx playwright test --shard=3/4
npx playwright test --shard=4/4
四个分片在不同的 CI job 里同时跑,总耗时约降到原来的四分之一。
Note分片默认按「文件」切。若开了
fullyParallel: true,则按「单条测试」切,分布更均衡。文件大小悬殊时,建议开 fullyParallel 或保持文件体量相近。
合并分片报告
每个分片各出一份报告,想看汇总,先在配置里用 blob 报告:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
reporter: process.env.CI ? 'blob' : 'html',
});
blob 报告默认落在 blob-report 目录,文件名自带分片号,不会撞车。各分片把它上传成 CI 产物,最后统一放进一个目录(比如 all-blob-reports),一条命令合并:
npx playwright merge-reports --reporter html ./all-blob-reports
这会生成一份完整的 HTML 报告到 playwright-report 目录。GitHub Actions 里常用 matrix 跑分片,再用一个 merge job 收尾。
失败自动重试
有些失败是偶发的——网络抖一下、动画没播完。与其一红就慌,让 Playwright 自动重试(Retries):
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
retries: process.env.CI ? 2 : 0, // CI 上失败重试两次,本地不重试
});
命令行也行:
npx playwright test --retries=2
重试时建议顺手收集 Trace(追踪),方便看那次失败到底发生了什么:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
retries: 2,
use: { trace: 'on-first-retry' }, // 只在第一次重试时录,开销小
});
重试一开,测试有三种结果:一次就过是 passed,重试后过是 flaky(不稳定),重试完还挂才算 failed。报告里这三类是分开统计的。
Tip重试能消化抖动,但掩盖不了真 bug。重试后仍然红,必须有人跟进,别指望它自愈。
快速失败:maxFailures
一套件几百条,早期就红了好几条,与其把剩下的也跑完浪费资源,可以设失败上限:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
maxFailures: process.env.CI ? 10 : undefined,
});
npx playwright test --max-failures=10
达到上限后立即停,未执行的测试跳过。
worker 编号的妙用
每个 worker 有两个编号:
workerIndex:全局唯一,从 1 起。worker 挂掉重启后,新进程拿到一个新的号。parallelIndex:范围是 0 到workers - 1。重启后保持不变,同时在跑的 worker 一定互不相同。
想给不同 worker 分配独立测试账号、避免抢同一份数据,用它们区分:
const userName = `user-${test.info().workerIndex}`;
也可以读环境变量 process.env.TEST_WORKER_INDEX 和 process.env.TEST_PARALLEL_INDEX,效果一样。配合 worker 级夹具(第 39 章),就能做到「每个 worker 一个独立账号」,并行也不打架。
组合拳建议
我常用的 CI 配置长这样:开 fullyParallel,按分片摊到多机,retries 设 2,trace 开 on-first-retry,maxFailures 设个十来个省资源。本地则 workers 放开、retries 关掉,跑得快也看得清。
做到这一步,你已经掌握 Playwright 测试框架的骨架:从拦截网络、复用登录态、直接测接口,到夹具、钩子、分组、并行与分片。接下来几章讲怎么把结果看明白——报告、截图视频、Trace 和视觉对比。
小结
这章把测试怎么跑快讲透了:开 fullyParallel 让多条同时跑,分片把一套摊到多台机器,retries 消化偶发抖动。几个容易踩的坑——retries 别在本地开,trace 跟着重试录才有用,workerIndex 拿来分账号并行才不打架。