如何在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
相关产品推荐
相关产品推荐

