使用Jest与Puppeteer实现并行测试遇到问题求助
Puppeteer + Jest 并行测试踩坑解决方案
嘿,我明白你现在的困扰:串行跑测试一切正常,但一用test.concurrent并行就出问题。根源其实很明显——你把browser和page声明成了全局变量!当Jest并行执行多个测试时,所有beforeEach钩子会同时启动,它们会互相覆盖这两个全局变量,导致测试用例之间串台:比如测试A刚打开页面,测试B的beforeEach就把page换成了自己的实例,A后续操作的其实是B的页面,不出问题才怪。
下面给你两个靠谱的修复方案,按需选择:
方案一:用块级变量替代全局变量
把browser和page的声明移到describe块内部,同时记得在afterEach里关闭浏览器,避免资源泄漏:
describe('我的并行测试集', () => { // 只在当前describe块内生效的变量,避免全局污染 let browser, page; const width = 1280; const height = 720; beforeEach(async () => { browser = await puppeteer.launch({ headless: false, // slowMo: 80, args: [`--window-size=${width},${height}`] }); page = await browser.newPage(); await page.setViewport({width, height}); }); // 每个测试结束后一定要关闭浏览器 afterEach(async () => { await browser.close(); }); test.concurrent("测试用例1", async () => { await page.goto('xxxx.com'); // 你的测试逻辑... }); test.concurrent("测试用例2", async () => { await page.goto('yyyy.com'); // 你的测试逻辑... }); });
方案二:每个测试用例独立初始化实例
如果你的测试不需要共享浏览器环境,这种方式最彻底——让每个测试自己创建和销毁浏览器,完全隔离:
const width = 1280; const height = 720; // 封装一个复用的页面创建函数,减少重复代码 const getNewPage = async () => { const browser = await puppeteer.launch({ headless: false, // slowMo: 80, args: [`--window-size=${width},${height}`] }); const page = await browser.newPage(); await page.setViewport({width, height}); return { browser, page }; }; test.concurrent("测试用例1", async () => { const { browser, page } = await getNewPage(); try { await page.goto('xxxx.com'); // 你的测试逻辑... } finally { // 不管测试成功失败,都要关闭浏览器 await browser.close(); } }); test.concurrent("测试用例2", async () => { const { browser, page } = await getNewPage(); try { await page.goto('yyyy.com'); // 你的测试逻辑... } finally { await browser.close(); } });
如果觉得每个测试都启动浏览器太慢,也可以研究下Puppeteer的浏览器池,但对大多数场景来说,上面两种方案已经能完美解决并行测试的冲突问题了。
内容的提问来源于stack exchange,提问作者jprabhan
相关产品推荐
相关产品推荐

