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

如何在Playwright中通过Fixture与POM实现项目参数化?

在Playwright中通过Fixture与POM实现多项目参数化

1. 定义应用专属配置与POM类

先把每个应用的专属数据(URL、 credentials)和对应的POM类绑定,统一管理:

// configs/appConfigs.ts
import { App1POM } from '../pom/App1POM';
import { App2POM } from '../pom/App2POM';

// 统一配置类型
type AppConfig = {
  url: string;
  credentials: { username: string; password: string };
  pomClass: typeof App1POM | typeof App2POM;
};

// 应用配置映射表
export const appConfigs: Record<string, AppConfig> = {
  app1: {
    url: 'https://app1.example.com',
    credentials: { username: 'app1_user', password: 'app1_pass' },
    pomClass: App1POM
  },
  app2: {
    url: 'https://app2.example.com',
    credentials: { username: 'app2_user', password: 'app2_pass' },
    pomClass: App2POM
  }
};

然后编写POM类,用基类统一接口,子类实现各自的业务逻辑:

// pom/basePOM.ts
export class BasePOM {
  protected page: Page;
  constructor(page: Page) {
    this.page = page;
  }

  // 定义通用接口,子类必须实现
  async login(credentials: { username: string; password: string }) {
    throw new Error('Login方法需子类实现');
  }
}

// pom/App1POM.ts
import { BasePOM } from './basePOM';

export class App1POM extends BasePOM {
  async login(credentials: { username: string; password: string }) {
    await this.page.fill('#username', credentials.username);
    await this.page.fill('#password', credentials.password);
    await this.page.click('#app1-login-btn');
  }
}

// pom/App2POM.ts
import { BasePOM } from './basePOM';

export class App2POM extends BasePOM {
  async login(credentials: { username: string; password: string }) {
    await this.page.fill('#email', credentials.username);
    await this.page.fill('#pass', credentials.password);
    await this.page.click('#app2-submit');
  }
}

2. 自定义Fixture自动注入配置与POM

扩展Playwright的test对象,创建自定义fixture,根据项目配置的appConfig自动匹配对应的配置和POM实例:

// test.setup.ts
import { test as base } from '@playwright/test';
import { appConfigs } from './configs/appConfigs';
import { BasePOM } from './pom/basePOM';

// 扩展test的类型定义
type TestFixtures = {
  appConfig: typeof appConfigs[string];
  pom: BasePOM;
};

export const test = base.extend<TestFixtures>({
  // 从项目配置中读取appConfig标识,获取对应配置
  appConfig: async ({}, use, testInfo) => {
    const appKey = testInfo.project.use.appConfig as string;
    const config = appConfigs[appKey];
    if (!config) throw new Error(`无效的appConfig: ${appKey}`);
    await use(config);
  },

  // 根据配置创建对应POM实例
  pom: async ({ page, appConfig }, use) => {
    const pomInstance = new appConfig.pomClass(page);
    await use(pomInstance);
  }
});

export { expect } from '@playwright/test';

3. 配置Playwright多项目

在playwright.config.ts中给每个项目指定appConfig,和浏览器配置放在一起:

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    {
      name: 'App 1',
      use: {
        ...devices['Desktop Chrome'],
        appConfig: 'app1' // 对应appConfigs中的key
      }
    },
    {
      name: 'App 2',
      use: {
        ...devices['Desktop Chrome'],
        appConfig: 'app2'
      }
    }
  ]
});

4. 编写复用的测试用例

直接用自定义的test对象,不用再判断应用类型,Fixture会自动注入对应配置和POM:

// tests/common.spec.ts
import { test, expect } from '../test.setup';

test('通用登录验证', async ({ page, appConfig, pom }) => {
  await page.goto(appConfig.url);
  await pom.login(appConfig.credentials);
  // 通用断言:验证跳转至仪表盘
  await expect(page).toHaveURL(/dashboard/);
});

运行测试时,Playwright会自动为每个项目执行用例,自动适配不同应用的专属逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:34:57