You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Playwright多Worker在UI自动化中的使用问题及优化咨询

问题

在Web应用UI自动化场景中,我想为基于Playwright的测试启用多Worker(X个)。目标应用需要先完成登录流程,之后才能访问Payments、Entity、Agent Bank等多个功能页面,每个页面有独立操作逻辑(比如Payment页面需填完必填字段才会启用SAVE按钮,完成支付创建)。

我的代码采用页面对象模型(POM),每个测试文件(如Payments、Entity)的test.describe块内,通过test.beforeAll钩子完成页面导航、登录等前置操作,后续包含多个测试用例。单Worker模式下运行正常,但未指定--worker参数由Playwright自动分配Worker数量时,会出现test.beforeAll超时错误。硬设置workers=1则一切正常。

请问结合应用特性,是否可以启用多Worker?若可行,需要对代码做哪些修改?

附示例代码

test.describe.serial('Payment Test Set', () => {
  test.use({ ignoreHTTPSErrors: true });
  let page;
  let paymentPage;
  let commonActions;
  let loginPage;
  let fileManager;

test.beforeAll(async ({ browser, baseURL }) => {
  const startTime = Date.now();
  const { LibraryForUploadingFileToPayment } = await import('./paymentFileUploader.mjs');
  page = await browser.newPage();
  paymentPage = new PaymentsPage(page);
  commonActions = new CommonActions(page);
  loginPage = new LoginPage(page);
  fileManager = new LibraryForUploadingFileToPayment();
  await page.goto(configJson.baseURL, { timeout: 20000, waitUntil: 
  'domcontentloaded'});
  console.log("Payments:Navigation to UAT successful");
  console.log('Page loaded in: ' + (Date.now() - startTime) + 'ms');

  await page.click('role=button[name="AGREE & CONTINUE"]');
  await page.fill('#userName', "xxxx");
  await page.fill('#password', "xxxx$");
  await page.click('role=button[name="LOGIN"]');
  await page.waitForTimeout(10000);

  await loginPage.loginForPaymentAutoTestClient();
  await commonActions.clickPaymentsLink();
});

test('Click ADD NEW button', async () => {
    await commonActions.clickAddNewButton();
});
test('Select Direction as PAY', async() => {
    await paymentPage.selectDirectionAsPay();
    paymentDetails.direction = "PAY";
});
test('Enter Amount', async() => {
    const randomNumber = paymentPage.generateRandomNumber();
    paymentDetails.amount = randomNumber
    await paymentPage.enterAmount(paymentDetails.amount);
});
test('Payment Details', async () => {
    console.log(paymentDetails);
});
test('More tests', {
});

test.afterAll(async () => {
    await page.context().clearCookies();
    await page.close();
  });
});

附playwright.config.js配置

import { defineConfig, devices } from '@playwright/test';
import path from 'path';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
workers: process.env.CI ? 1 : undefined,
reporter: [
/* Uncomment the below line before deploying to AWS */
['html', { 
  outputFolder: 'test-results', 
  open: 'never', 
  embed: true,
 }],
   ['line'],
      ['junit', { outputFile: 'reports/results.xml' }],
   ['json', { outputFile: 'reports/results.json' }],
],
use: {
  ignoreHTTPSErrors: true,
  viewport: { width: 1920, height: 1080 },
  actionTimeout: 15000,
  navigationTimeout: 50000, 
  timeout: 60000,
  trace: 'on-first-retry',
  screenshot: 'only-on-failure',
  headless: true
},

projects: [
{
  name: 'chromium',
  use: { 
    browserName: 'chromium',
    launchOptions: {
      args: ['--ignore-certificate-errors']
      }
    },
  },
 ]
});

本地执行命令

npx playwright test ./tests/AgentBankPage ./tests/Payments ./tests/Entity  --headed --reporter=html

回答

能否启用多Worker?

完全可以启用多Worker。你的测试套件(Payments、Entity等)本身是独立的,每个套件对应不同功能页面,只要解决多Worker并行时的资源冲突和前置操作稳定性问题即可。

需要修改的内容

1. 优化beforeAll中的不稳定操作

多Worker并行时,页面加载和操作的资源竞争会放大不稳定操作的影响,需针对性修复:

  • 替换固定等待page.waitForTimeout(10000):硬编码等待时间不可靠,改为等待登录后的关键元素或网络请求完成,确保页面状态就绪:
    // 替换原固定等待代码
    await page.waitForSelector('role=link[name="Payments"]', { timeout: 15000 });
    
  • 调整goto的等待策略:将waitUntil: 'domcontentloaded'改为networkidle,等待网络空闲后再执行后续操作,避免页面未完全加载导致的元素找不到问题:
    await page.goto(configJson.baseURL, { timeout: 20000, waitUntil: 'networkidle'});
    
  • 避免全局变量共享:如果paymentDetails是全局变量,多Worker并行时会被不同套件修改导致状态混乱,改为在describe块内声明局部变量:
    test.describe.serial('Payment Test Set', () => {
      let paymentDetails = {}; // 局部变量,每个Worker的套件独立拥有
      // ... 其他代码
    });
    

2. 调整Playwright配置

  • 手动设置合理的Worker数量:本地默认会根据CPU核心数分配Worker,过多Worker会导致资源耗尽,可手动设置与测试文件数量匹配的值(比如3个测试文件对应workers:3):
    // playwright.config.js
    workers: process.env.CI ? 1 : 3,
    
  • 按需增加超时时间:并行时页面加载和操作可能变慢,适当调大全局超时阈值:
    use: {
      // ...
      navigationTimeout: 60000, // 从50000调整为60000
      timeout: 90000, // 从60000调整为90000
    }
    

3. 检查应用并发登录限制

部分应用会限制同一账号的并发登录会话数,多Worker并行时可能触发该限制导致登录超时。如果是这种情况:

  • 使用多个测试账号,让不同Worker使用不同账号登录
  • 联系应用管理员调整并发会话限制

4. 保留合理的串行/并行逻辑

你当前使用的test.describe.serial会强制套件内的测试用例串行执行,这适合Payment这类连贯操作的测试流程,无需修改;不同套件之间仍可通过多Worker并行执行,不影响整体效率。

修改后的Payment测试文件片段

test.describe.serial('Payment Test Set', () => {
  test.use({ ignoreHTTPSErrors: true });
  let page;
  let paymentPage;
  let commonActions;
  let loginPage;
  let fileManager;
  let paymentDetails = {}; // 改为局部变量

  test.beforeAll(async ({ browser, baseURL }) => {
    const startTime = Date.now();
    const { LibraryForUploadingFileToPayment } = await import('./paymentFileUploader.mjs');
    page = await browser.newPage();
    paymentPage = new PaymentsPage(page);
    commonActions = new CommonActions(page);
    loginPage = new LoginPage(page);
    fileManager = new LibraryForUploadingFileToPayment();
    
    // 改用networkidle等待页面加载完成
    await page.goto(configJson.baseURL, { timeout: 20000, waitUntil: 'networkidle'});
    console.log("Payments:Navigation to UAT successful");
    console.log('Page loaded in: ' + (Date.now() - startTime) + 'ms');

    await page.click('role=button[name="AGREE & CONTINUE"]');
    await page.fill('#userName', "xxxx");
    await page.fill('#password', "xxxx$");
    await page.click('role=button[name="LOGIN"]');
    
    // 替换固定等待,改为等待登录后的关键元素
    await page.waitForSelector('role=link[name="Payments"]', { timeout: 15000 });

    await loginPage.loginForPaymentAutoTestClient();
    await commonActions.clickPaymentsLink();
  });

  // ... 测试用例保持不变

  test.afterAll(async () => {
    await page.context().clearCookies();
    await page.close();
  });
});

内容的提问来源于stack exchange,提问作者Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:23:09