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

如何在Playwright中避免每次测试都执行认证操作?

问题:Playwright循环测试中beforeAll重复执行认证

技术栈

  • Node.js
  • TypeScript
  • Angular

测试配置

测试中通过test.beforeAll使用estimatePage fixture,该fixture依赖homePage fixture,认证流程在homePage fixture中完成。

fixtures.ts

export const test = base.extend<fixtures>({
  // Default estimate if estimate isn't provided in the test.
  testEstimateName: '',
  homePage: async ({ page }, use) => {
    // Use exact url as UI mode tends to fail with base url.
    await page.goto(`${process.env.TARGET}${process.env.LANGUAGE}`);

    const loginPage: LoginPage = new LoginPage(page);
    await page.waitForURL(/login.microsoftonline.com/, { waitUntil: Consts.DOM_CONTENT_LOAD });

    // Log into app
    await loginPage.login();

    // Home page
    await page.waitForURL(process.env.LANGUAGE, { waitUntil: Consts.DOM_CONTENT_LOAD });
    const homePage: HomePage = new HomePage(page);

    // Use the fixture value in the test.
    await use(homePage);

    // Clean up the fixture.
    await homePage.page.close();
  },
  estimatePage: async ({ homePage, testEstimateName }, use) => {
    const estName: string = testEstimateName;
    const currentPage: Page = await homePage.openEstimate(estName);
    const estimatePage = new EstimatePage(currentPage);

    // Use the fixture value in the test.
    await use(estimatePage);

    // Clean up the fixture.
  },
});

test.spec.ts

let estimatePageVal: EstimatePage;
let commonFunctions: CommonFunctions;

// Override the default estimate in the fixture
const estimateName: string = '';
test.use({ testEstimateName: `${estimateName}` });

test.beforeAll(async ({ estimatePage }) => {
  estimatePageVal = estimatePage as EstimatePage;
  commonFunctions = new CommonFunctions(estimatePageVal.page) as CommonFunctions;
});

test.describe('Estimate Line Extension', () => {
  for (let i: number = 0; i < Inputs.length; i++) {
    const input: InputData = Inputs[i];
    const output: OutputData = Outputs[i];
    let detailRowData: UnionModel;
    test(`Test #${i + 1}`, async () => {
      // Switch sheetname to detail
      await estimatePageVal.switchSheet(Consts.DETAIL);
      const sheetName: string = await estimatePageVal.getSheetName();
      await expect(sheetName).toEqual(Consts.DETAIL);

      const bidItem: string = (await estimatePageVal.getCellValue(65, BindColsCEUP.BID_ITEM, sheetName)) as string;
      await expect(bidItem).toEqual('NEW');
    });
  }
});

问题现象

原本期望test.beforeAll仅执行一次认证,循环内的所有测试复用已认证页面,但实际每个测试运行时,test.beforeAll都会重新执行认证流程,测试在VSCode UI调试模式下运行。

解决方案

要实现多个测试间复用已认证页面,需调整Playwright fixture的作用域并优化测试结构:

  1. 修改fixture作用域:
    Playwright默认fixture为测试级(每个测试重新创建实例),需将homePage和estimatePage fixture的作用域改为描述块级(同一describe内复用),添加scope: 'describe'配置:

    homePage: async ({ page }, use) => {
      // 原有认证逻辑不变
    }, { scope: 'describe' }) // 指定作用域为describe块
    
    estimatePage: async ({ homePage, testEstimateName }, use) => {
      // 原有逻辑不变
    }, { scope: 'describe' })
    

    若需全局所有测试复用认证,可设置scope: 'global',但需注意测试间的状态隔离问题。

  2. 避免全局变量存储fixture实例:
    不要将fixture实例赋值给外部全局变量(如estimatePageVal),应直接在测试函数中注入fixture,或通过fixture的复用机制共享状态。

  3. 确保测试结构匹配作用域:
    循环生成的测试需放在同一个describe块内,确保fixture的作用域覆盖所有需要复用认证的测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:13:21