如何在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的作用域并优化测试结构:
修改fixture作用域:
Playwright默认fixture为测试级(每个测试重新创建实例),需将homePage和estimatePagefixture的作用域改为描述块级(同一describe内复用),添加scope: 'describe'配置:homePage: async ({ page }, use) => { // 原有认证逻辑不变 }, { scope: 'describe' }) // 指定作用域为describe块 estimatePage: async ({ homePage, testEstimateName }, use) => { // 原有逻辑不变 }, { scope: 'describe' })若需全局所有测试复用认证,可设置
scope: 'global',但需注意测试间的状态隔离问题。避免全局变量存储fixture实例:
不要将fixture实例赋值给外部全局变量(如estimatePageVal),应直接在测试函数中注入fixture,或通过fixture的复用机制共享状态。确保测试结构匹配作用域:
循环生成的测试需放在同一个describe块内,确保fixture的作用域覆盖所有需要复用认证的测试。
内容的提问来源于stack exchange,提问作者diogenes31
相关产品推荐
相关产品推荐

