Playwright性能优化:减少测试执行时间的10个技巧

当你的E2E测试套件执行时间从几分钟膨胀到半小时,每天能完整运行的次数屈指可数时,优化就不再是可选项,而是必需品。我们团队曾面对一个45分钟的测试套件,通过系统优化最终将其缩减到8分钟。以下是经过实战验证的10个技巧。

1. 并行化:性价比最高的优化

这是最能立竿见影的手段。Playwright原生支持并行执行,你只需要调整配置:

// playwright.config.ts export default { workers: process.env.CI ? 4 : 2, // CI环境用4个worker,本地用2个 fullyParallel: true, // 所有测试文件并行执行 // 如果你的测试有状态依赖,可以改为: // fullyParallel: false, // 但依然可以保持worker数量 };

关键在于测试文件的独立性。如果有全局状态(如共享数据库),你需要通过beforeAllafterAll来管理测试隔离。在我们的实践中,仅开启并行化就将执行时间减少了65%。

2. 浏览器复用:减少启动开销

每次测试都启动新浏览器会浪费大量时间。改为复用浏览器实例:

// 在配置中开启 exportdefault { use: { headless: true, // 复用浏览器上下文而非每次都创建新的 launchOptions: { args: ['--no-sandbox'] } }, }; // 测试文件中 test.describe.configure({ mode: 'parallel' }); // 让describe内测试也并行 // 或者手动管理浏览器实例 let browser: Browser; test.beforeAll(async () => { browser = await chromium.launch(); }); test.beforeEach(async ({ page }) => { // 从已有浏览器创建上下文 const context = await browser.newContext(); page = await context.newPage(); });

注意:浏览器复用可能导致测试间状态污染,确保每个测试有独立的browserContext

3. 选择性执行:只跑必要的测试

不是每次提交都需要跑全部测试。建立分层策略:

{ "scripts": { "test:smoke": "playwright test --grep '@smoke'", "test:regression": "playwright test --grep '@regression'", "test:changed": "playwright test $(git diff --name-only HEAD~1 | grep -E '\\.spec\\.ts$')" } }

在测试文件中使用标签:

test('关键登录流程 @smoke', async ({ page }) => { // 冒烟测试,每次CI都执行 }); test('边界条件测试 @regression', async ({ page }) => { // 回归测试,每日执行 });

我们团队设置了预提交钩子只跑@smoke测试,夜间CI跑完整套件,平衡了速度和覆盖率。

4. 智能等待:告别硬编码sleep

硬编码的sleep是性能杀手,也是脆弱的根源:

// ❌ 糟糕的做法 await page.waitForTimeout(5000); // 无论实际需要多久都等5秒 // ✅ 正确的做法 // 等待页面加载完成 await page.waitForLoadState('networkidle'); // 等待特定元素出现 await page.locator('.data-loaded').waitFor({ state: 'visible' }); // 等待API请求完成 const responsePromise = page.waitForResponse('/api/data'); await page.click('#load-data'); const response = await responsePromise; // 自定义等待条件 await page.waitForFunction( () =>document.querySelectorAll('.item').length >= 10 );

优化后,我们的测试平均等待时间从固定的5秒降到了0.5-2秒,具体取决于网络和业务逻辑。

5. 数据准备:预置而非动态生成

避免在测试中执行耗时操作:

// ❌ 每个测试都创建用户 test('用户操作', async () => { const user = await createUserViaAPI(); // 每次调用都走完整流程 // 测试逻辑... }); // ✅ 预置测试数据 // 在全局setup中 import { seedDatabase } from'./test-data'; asyncfunction globalSetup() { await seedDatabase({ standardUsers: 5, adminUsers: 1, products: 50 }); } // 测试中直接使用 test('用户操作', async ({ page }) => { await page.goto(`/user/${process.env.TEST_USER_ID}`); // 使用预置用户 // 测试逻辑... });

我们为测试环境准备了快照数据库,每个测试套件开始时恢复快照,这比每个测试都清理数据快得多。

6. 资源拦截:阻止不必要的加载

页面加载的图片、字体、分析脚本对测试毫无价值:

// 在配置中或beforeEach中 await page.route('**/*.{png,jpg,jpeg,gif,svg}', route => route.abort()); await page.route('**/analytics.js', route => route.abort()); await page.route('**/ads/*', route => route.abort()); // 或者更精细的控制 await page.route('**/*', route => { const resourceType = route.request().resourceType(); // 只允许必要的资源类型 const blockedTypes = ['image', 'media', 'font']; if (blockedTypes.includes(resourceType)) { return route.abort(); } return route.continue(); });

这个简单的拦截策略让我们的页面加载时间平均减少了40%。

7. 测试分割:平衡并行和串行

不是所有测试都能完美并行。混合策略效果更好:

// 配置文件 exportdefault { // 为串行测试创建单独的项目 projects: [ { name: '串行-关键路径', testMatch: '**/*.critical.spec.ts', fullyParallel: false, workers: 1 }, { name: '并行-功能测试', testMatch: '**/*.spec.ts', testIgnore: '**/*.critical.spec.ts', fullyParallel: true, workers: 4 } ] }; // 或者在同一文件中混合 test.describe.serial('用户注册流程', () => { // 这些测试有严格顺序依赖 test('步骤1: 填写信息', () => {}); test('步骤2: 验证邮箱', () => {}); test('步骤3: 完善资料', () => {}); }); test.describe('商品浏览功能', () => { // 这些测试可并行 test('搜索商品', () => {}); test('筛选结果', () => {}); test('排序商品', () => {}); });

8. 缓存利用:复用登录状态

登录通常是测试中最耗时的部分:

// storageState.ts - 创建可复用的认证状态 import { test as setup } from'@playwright/test'; setup('准备登录状态', async ({ page }) => { await page.goto('/login'); await page.fill('#username', 'testuser'); await page.fill('#password', 'password123'); await page.click('#submit'); await page.waitForURL('/dashboard'); // 保存状态 await page.context().storageState({ path: 'playwright/.auth/user.json' }); }); // playwright.config.ts exportdefault { use: { // 所有测试复用该状态 storageState: 'playwright/.auth/user.json' }, globalSetup: require.resolve('./storageState.ts') }; // 测试文件中直接访问已登录页面 test('访问仪表盘', async ({ page }) => { await page.goto('/dashboard'); // 已经是登录状态 // 无需再次登录 });

注意:定期更新缓存状态,避免会话过期。

9. 基础设施优化:硬件和环境

软件优化到极限后,看看硬件:

# GitHub Actions示例 jobs: test: runs-on:ubuntu-latest strategy: matrix: shard:[1,2,3,4]# 分片执行 steps: -uses:actions/setup-node@v3 with: node-version:'18' -run:| # 只安装必要依赖 npm ci --omit=dev --ignore-scripts # 单独安装测试相关依赖 npm install @playwright/test playwright -run:| # 分片执行 npx playwright test --shard=${{ matrix.shard }}/${{ strategy.job-total }} -uses:actions/upload-artifact@v3 if:always() with: name:playwright-report-${{matrix.shard}} path:playwright-report/

本地开发时,确保Node.js是最新LTS版本(V8引擎的持续优化能提升执行速度),考虑使用SSD而非HDD。

10. 持续监控:建立性能基线

优化不是一劳永逸的。建立监控机制:

// 收集性能指标 test('性能回归检查', async ({ page }) => { const startTime = Date.now(); // 执行关键操作 await page.goto('/dashboard'); await page.click('#load-report'); await page.waitForSelector('.report-loaded'); const duration = Date.now() - startTime; // 记录到文件或外部系统 console.log(`执行时间: ${duration}ms`); // 断言性能要求 expect(duration).toBeLessThan(3000); // 必须小于3秒 }); // 使用Playwright的trace功能分析慢测试 exportdefault { use: { trace: process.env.CI ? 'on-first-retry' : 'retain-on-failure', // 或者只为慢测试记录trace trace: { mode: 'on', snapshots: true, screenshots: true } } };

我们团队设置了一个仪表板,跟踪每次提交的测试执行时间,当某个测试突然变慢时立即告警。

实战组合拳

没有单一银弹,真正有效的是组合策略。我们的优化路径是:先上并行化(见效最快),然后优化等待逻辑和数据准备,接着实现分层测试和资源拦截,最后通过基础设施和监控巩固成果。

记住:优化应该基于数据。使用--reporter=line查看每个测试的时间,优先优化最耗时的10%的测试。有些测试可能本身就应该是慢的(如完整业务流程),不要过度优化。

现在,你们的测试套件还在苦苦挣扎吗?从第一点开始,今天就能看到效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1169165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java【四则运算计算器】_java四则运算计算器,零基础入门到精通,收藏这篇就够了

Swing 编程 Swing 是 Java 基类的一部分,是基于 AWT 开发的;AWT 是 Java 语言开发用户界面程序的基本工具包,是 Swing 的基础。Swing 提供了大量的轻量级组件,还提供了一个用于实现包含插入式界面样式等特性的 GUI 的下层构件&am…

基于VUE的轻琢线条塑形管理系统[VUE]-计算机毕业设计源码+LW文档

摘要:随着健身行业的发展,高效的管理系统对于塑形机构至关重要。本文介绍基于VUE的轻琢线条塑形管理系统,阐述其采用的关键技术,分析系统需求,包括用户管理、教练信息管理等功能需求,详细描述系统设计中的架…

电子手轮控制步进电机程序探索

电子手轮控制步进电机程序手轮控制步进电机的頻率,脉冲数,内容包括欧姆龙plc程序,mcgs程序。 内容不复杂,用别的plc也可以实现。在自动化控制领域,通过电子手轮精准控制步进电机的频率与脉冲数是一项常见且关键的任务。…

2026年1月哪些房产中介管理系统客户管理功能完善

在房产经纪行业数字化转型加速的2026年,客户资源已成为中介企业核心竞争力的关键。一套客户管理功能完善的房产中介管理系统,不仅能帮助经纪人精准把握客户需求、提升跟进效率,更能助力企业实现客户资源的规范化沉淀与高效转化。不少中介从业…

基于VUE的企业员工工资管理系统[VUE]-计算机毕业设计源码+LW文档

摘要:企业员工工资管理是企业管理中的关键环节,传统管理方式效率低且易出错。本文介绍基于VUE的企业员工工资管理系统,阐述其采用的技术,深入分析系统在员工信息管理、工资计算、统计等方面的需求,详细描述系统设计过程…

基于 MATLAB 的机械故障诊断技术

1.基于 MATLAB 的机械故障诊断技术案例教程(包含 第1章 认识MATLAB 1.1 MATLAB简介 1.1.1 MATLAB概述 1.1.2 MATLAB的功能特点 1.2 MATLAB的用户界面 1.3 MATLAB矩阵运算 1.3.1 MATLAB中的变量 1.3.2 基本矩阵的操作 1.3.3 稀疏矩阵 1.3.4 矩阵的运算 1.4 MATLAB的编…

风速发电预测(线性回归模型 、XGBoost模型 、决策树回归模型 、随机森林回归模型 、梯度提升回归模型与LSTM模型对比,多特征输入,单标签输出,可轻易替换为其它时序数据集)

1.前言 1.1.运行效果:风速发电预测(线性回归模型 、XGBoost模型 、决策树回归模型 、随机森林回归模型 、梯度提升回归模型与LSTM模型对比,多特征输入,单标签输出,可轻易替换_哔哩哔哩_bilibili 1.2.环境库&#xff…

【无人机控制】基于 6 维简化线性模型设计 LQR 最优控制器,实现无人机三维定点位置跟踪附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 🍎 往期回顾关注个人主页:Matlab科研工作室 👇 关注我领取海量matlab电子书和数学建模资料 &#…

【无人机路径规划】基于粒子群PSO、灰狼优化GWO、鲸鱼优化WOA的多无人机协同三维航迹规划考虑航程 高度 雷达威胁 火炮威胁 时间协同 空间避撞 航角约束 禁飞区附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 🍎 往期回顾关注个人主页:Matlab科研工作室 👇 关注我领取海量matlab电子书和数学建模资料 &#…

【深度好文】大模型智能体开发全攻略:64张图解析14项关键技术,小白也能轻松掌握

基于大语言模型(LLM)的 AI 智能体正在变得越来越普遍,似乎正在取代我们 熟悉的“常规”对话式 LLM。这些令人惊叹的能力并非轻易就能实现,需要许多组件协同工作。在这篇文章中,我们将通过64张图,探索 AI 智…

【收藏必备】2026年AI核心关键词:智能体(Agent)六大工作流设计模式,助你构建会思考的系统

2026年AI最大关键字无疑是:智能体(Agent)。 从医疗领域的「全病程智能诊疗助手」,到工业场景的「产线动态调度 Agent」;从政务大厅的「多业务协同办理终端」,到消费端的「跨平台智能客服中枢」,…

收藏必看:AI、机器学习和深度学习:从零开始理解大模型的基础概念与联系

现在AI,大模型等各种时髦新潮词汇层出不穷,说起来都是与人工智能相关的,那人工智能,机器学习,深度学习到底具体是什么?它们之间有什么联系与区别?1.基本概念 1.1人工智能(artificial…

数字员工是什么?熊猫智汇在现代企业中的应用价值有哪些?

数字员工在现代企业中扮演着愈发重要的角色,尤其是在优化业务流程、降低运营成本和提升效率方面。通过AI销冠系统的应用,企业可以实现系统化的流程自动化,从而显著减少人工操作带来的时间和成本消耗。这种智能化转变不仅提高了任务完成的准确…

程序员必备:大模型算力概念速成,收藏这篇就够了

你是否曾被“FLOPS”、“显存”、“Token”这些围绕大模型的神秘术语搞得晕头转向?就像想学烹饪却被“焯水”、“炝锅”、“勾芡”劝退一样,面对大模型的算力世界,零基础的你也许正站在门口踌躇。 别担心!这篇“零基础学大模型&am…

【图像检测】基于粒子群算法优化SVM实现病灶图片训练与测试分类,gabor小波纹理特征提取附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 🍎 往期回顾关注个人主页:Matlab科研工作室 👇 关注我领取海量matlab电子书和数学建模资料 &#…

企业级安康旅游网站管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 随着旅游业的快速发展,安康地区凭借其独特的自然景观和丰富的文化资源吸引了大量游客。然而,传统的旅游管理模式难以满足现代游客的个性化需求,尤其是在信息查询、行程规划和服务反馈等方面存在效率低下、数据分散等问题。为了提高旅游管…

Java计算机毕设之基于vue野生濒危物种公益救助交流平台基于SpringBoot濒危物种公益救助交流平台(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

Java Web 学生宿舍信息系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着高校信息化建设的不断推进,学生宿舍管理作为校园生活的重要组成部分,亟需通过数字化手段提升管理效率和服务质量。传统宿舍管理多依赖人工操作,存在信息更新滞后、数据统计繁琐、安全隐患排查困难等问题。学生宿舍信息系统通过整合住…

【TextSorter Pro】我基于 Flutter × HarmonyOS 6开发了一款跨平台文本排序工具

【TextSorter Pro】我基于 Flutter HarmonyOS 6开发了一款跨平台文本排序工具 前言 在日常工作和学习中,我们经常需要对大量文本数据进行排序,比如整理名单、处理日志或分析数据。手动操作既费时又容易出错。为此,我基于 Flutter Harmony…

大模型实战:零代码搭建智能体,3分钟批量生成爆款图文,小白必备收藏

最近小红薯上的这种内容特别火?但是手动制作这种图文内容真的太费时间了! 要查资料、写文案、做排版、找配图…,一套流程下来已经过去大半天了。今天就来教大家一个超实用的技巧——用扣子(Coze)工作流搭建一个智能体&…