Playwright数组测试重复执行:无需修改配置的解决方法咨询
Playwright多浏览器测试重复执行问题解决
问题描述
我是Playwright新手,异步编程经验有限。运行以下代码时会生成8-9张重复截图,已确认是测试并行执行导致,尝试串行执行未果,仅能通过--workers=1参数解决。现咨询如何修改代码,使browserTypes数组中每个浏览器仅执行一次测试,无需修改playwright.config或使用workers参数。
原测试代码:
import { test, chromium, firefox, webkit } from '@playwright/test'; test("Browser support test", async () => { const browserTypes = [chromium, firefox, webkit]; const now = new Date(); const timestamp = now.toISOString().replace(/[:.]/g, "-"); for (const browserType of browserTypes) { console.log(`Running: ${browserType.name()}`); const browser = await browserType.launch(); const page = await browser.newPage(); await page.goto("https://www.whatsmybrowser.org/"); await page.screenshot({ path: `tests-screenshots/pw-${browserType.name()}-${timestamp}.png`, }); await browser.close(); } });
补充配置说明
原配置开启全并行及多项目配置引发该问题,简化配置后问题解决:
原配置:
export default defineConfig({ testDir: './tests', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: 'html', use: { trace: 'on-first-retry', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, { name: 'firefox', use: { ...devices['Desktop Firefox'] }, }, { name: 'webkit', use: { ...devices['Desktop Safari'] }, } ] });
简化后配置:
export default defineConfig({ testDir: './tests', reporter: 'html', retries: 0 });
问题根源
原配置中projects定义了3个浏览器项目,加上fullyParallel: true,Playwright会同时启动3个进程分别执行每个项目。而单个测试用例里又循环启动3个浏览器,导致每个项目进程都会执行一次循环,最终生成3×3=9张截图。--workers=1是强制仅用1个工作进程,所以只会执行一次循环,生成3张截图。
解决方案
方案一:匹配项目与浏览器,避免重复循环
通过判断当前运行的项目名称,只启动对应浏览器,每个项目仅执行一次测试:
import { test, chromium, firefox, webkit } from '@playwright/test'; // 配置测试组串行执行,禁用并行 test.describe.configure({ mode: 'serial', fullyParallel: false }); test.describe('Browser support test', () => { // 映射项目名称到对应的浏览器类型 const browserMap = { chromium, firefox, webkit }; test(`Test current browser`, async ({}) => { // 获取当前运行的项目名称 const currentProject = test.info().project.name; const browserType = browserMap[currentProject]; if (!browserType) return; const now = new Date(); const timestamp = now.toISOString().replace(/[:.]/g, "-"); console.log(`Running: ${browserType.name()}`); const browser = await browserType.launch(); const page = await browser.newPage(); await page.goto("https://www.whatsmybrowser.org/"); await page.screenshot({ path: `tests-screenshots/pw-${browserType.name()}-${timestamp}.png`, }); await browser.close(); }); });
方案二:强制测试组串行执行
直接在代码中配置测试组为串行,即使原配置开启并行,该测试组也会按顺序执行一次循环:
import { test, chromium, firefox, webkit } from '@playwright/test'; // 强制该测试组串行执行,避免多进程重复执行循环 test.describe.configure({ mode: 'serial' }); test("Browser support test", async () => { const browserTypes = [chromium, firefox, webkit]; const now = new Date(); const timestamp = now.toISOString().replace(/[:.]/g, "-"); for (const browserType of browserTypes) { console.log(`Running: ${browserType.name()}`); const browser = await browserType.launch(); const page = await browser.newPage(); await page.goto("https://www.whatsmybrowser.org/"); await page.screenshot({ path: `tests-screenshots/pw-${browserType.name()}-${timestamp}.png`, }); await browser.close(); } });
内容的提问来源于stack exchange,提问作者forcequitIO
相关产品推荐
相关产品推荐

