如何在Playwright(JavaScript)多文件测试中复用同一页面上下文
Playwright跨文件复用浏览器上下文并按顺序执行测试的可行方案
方案一:统一入口文件+自定义测试套件(推荐)
这种方式完全由你控制测试顺序和上下文生命周期,适合需要严格按指定顺序执行的场景:
- 创建全局测试入口文件(比如
test-entry.spec.js),在这里完成上下文初始化,并按顺序导入执行各个测试函数:
const { test: base } = require('@playwright/test'); // 导入分散在不同文件的测试函数 const loginTest = require('./tests/login'); const checkoutTest = require('./tests/checkout'); const profileTest = require('./tests/profile'); // 自定义测试套件,复用同一个浏览器上下文 const test = base.extend({ page: async ({ browser }, use) => { // 只创建一次上下文和page const context = await browser.newContext(); const page = await context.newPage(); // 将page传递给所有测试用例 await use(page); // 所有测试执行完毕后再关闭上下文 await context.close(); }, }); // 按你需要的顺序执行测试 test('执行登录测试', async ({ page }) => { await loginTest(page); }); test('执行结算测试', async ({ page }) => { await checkoutTest(page); }); test('执行个人信息测试', async ({ page }) => { await profileTest(page); });
- 单个测试文件的写法(比如
login.js),导出接收page参数的测试函数:
module.exports = async (page) => { await page.goto('/login'); await page.fill('#username', 'test-user'); await page.fill('#password', 'test-pass'); await page.click('#submit-btn'); // 其他登录相关测试逻辑 };
执行这个入口文件时,Playwright会用单个worker运行所有测试,且全程复用同一个浏览器上下文和page对象,顺序完全按你在入口文件中编写的顺序执行。
方案二:单Worker模式+全局上下文管理器
如果不想大幅修改现有测试文件结构,可以通过强制单Worker+全局变量共享上下文:
- 修改Playwright配置文件(
playwright.config.js),强制使用单个Worker:
module.exports = { workers: 1, // 强制所有测试在单个Worker中运行 use: { baseURL: 'https://your-app.com', // 其他配置项 }, };
- 创建上下文管理工具(比如
context-manager.js),负责全局上下文的创建、获取和清理:
let globalContext = null; let globalPage = null; // 获取复用的page对象 async function getSharedPage(browser) { if (!globalContext) { globalContext = await browser.newContext(); globalPage = await globalContext.newPage(); } return globalPage; } // 所有测试完成后清理上下文 async function cleanupContext() { if (globalContext) { await globalContext.close(); globalContext = null; globalPage = null; } } module.exports = { getSharedPage, cleanupContext };
- 在每个测试文件中使用管理器:
const { test } = require('@playwright/test'); const { getSharedPage, cleanupContext } = require('../context-manager'); // 全局前置:初始化上下文(仅第一次执行时创建) test.beforeAll(async ({ browser }) => { await getSharedPage(browser); }); // 全局后置:所有测试完成后清理 test.afterAll(async () => { await cleanupContext(); }); test('登录测试', async ({ browser }) => { const page = await getSharedPage(browser); // 测试逻辑... });
这种方式下,因为强制单Worker,全局变量可以安全共享,所有测试文件会复用同一个上下文。测试顺序默认按文件名称排序,若需要自定义顺序,可配合Playwright的test.describe.serial或者调整文件命名前缀(比如01-login.spec.js、02-checkout.spec.js)。
内容的提问来源于stack exchange,提问作者Marius Krenevičius
相关产品推荐
相关产品推荐

