资讯动态

e2e测试实战:从profile1配置到Playwright核心用例设计

发布时间:2026/10/26 7:52:57 来源:尧图企业网站定制
1. 从“e2e”这个标题说起它到底指什么第一次看到“e2e”这个标题很多人会愣一下。三个字母加一个数字既不像一个完整的产品名也不像一句能直接读懂的话。但如果你在软件测试、自动化工程或者质量保障这条线上待过一段时间就会立刻反应过来——这是“end to end”的缩写也就是端到端。而后面跟着的“profile1”则大概率是某个测试配置文件的命名或者某个测试套件的标识符。我先把话说直白一点e2e 测试就是从用户真实使用路径的起点一路验证到终点的自动化测试方式。它不关心某个函数内部怎么实现也不关心某个接口返回的字段是不是符合预期它只关心一件事——用户从打开页面、点击按钮、填写表单、提交数据到最后看到结果这一整条链路是不是通的、是不是对的。那“profile1”又是什么在实际工程里e2e 测试通常不会只有一套配置。你可能需要针对不同环境跑不同的用例比如本地开发环境、集成测试环境、预发布环境也可能需要针对不同浏览器、不同设备、不同用户角色来分别执行。这时候工程上就会用“profile”来区分这些配置组合。profile1 往往就是默认的那一套或者是最先被定义出来的那一套。这个标题背后真正要解决的问题其实非常具体当你的系统越来越复杂模块越来越多依赖越来越深的时候怎么保证用户走完一整条路不会掉进坑里。单元测试能保证每个零件是好的集成测试能保证零件之间接上了但只有 e2e 测试能告诉你用户真正走一遍会不会摔跤。适合看这篇内容的人我大致分三类。第一类是刚接触自动化测试的工程师你可能写过一些单元测试但对 e2e 还停留在“听说过”的阶段。第二类是已经有一堆 e2e 用例但跑得不太顺的团队用例经常挂、排查成本高、维护起来很痛苦。第三类是对质量保障体系有整体规划需求的技术负责人你需要知道 e2e 在整个测试金字塔里应该占什么位置、投多少资源、怎么和 CI/CD 串起来。接下来我会围绕 e2e 测试的核心设计思路、关键细节、实操过程以及常见问题排查把我自己踩过的坑和总结出来的经验完整展开。profile1 这个配置标识我也会在实操部分具体说明它通常怎么组织、怎么切换、怎么避免配置混乱。2. e2e 测试的整体设计与思路拆解2.1 为什么单元测试和集成测试不够用很多人一开始会觉得我把单元测试覆盖率做到百分之八九十集成测试也写了不少应该够了吧。但实际项目里你会发现一个很尴尬的现象单元测试全绿集成测试也全绿可用户一用就出问题。原因不复杂。单元测试验证的是函数级别的逻辑它把外部依赖全部 mock 掉了。集成测试验证的是模块之间的接口它通常也只关注数据能不能传过去、格式对不对。但用户真实操作的时候面对的是浏览器渲染、网络延迟、异步加载、第三方服务响应、权限校验、页面跳转、状态保持这一整套东西。任何一个环节出问题用户看到的就是白屏、报错、按钮点不动、数据没保存。我举个实际例子。之前有个项目单元测试里计算逻辑完全正确集成测试里接口返回也完全正确但用户提交表单后就是看不到成功提示。查了半天发现是前端在接口返回后需要先关闭弹窗、再刷新列表、再弹出提示而关闭弹窗的动画还没结束就触发了刷新导致提示被覆盖了。这种问题单元测试和集成测试根本覆盖不到只有 e2e 测试能抓住。所以 e2e 测试的核心价值不是替代单元测试和集成测试而是补上“真实用户路径”这一层验证。它站在用户的角度把整个系统当成一个黑盒只关心输入和输出。2.2 测试金字塔里 e2e 应该占多少测试金字塔这个概念很多人都听过底层是大量单元测试中间是适量集成测试顶层是少量 e2e 测试。但“少量”到底是多少很多人没有概念。我的经验是e2e 测试的用例数量应该控制在总用例数的百分之五到百分之十之间。一个中等规模的系统单元测试可能几千个集成测试几百个e2e 测试几十个到一百多个就差不多了。为什么不能多因为 e2e 测试的运行成本太高了。它要启动浏览器、要连真实数据库、要等网络请求、要处理异步时序跑一轮下来可能十几分钟甚至半小时。如果你有几百个 e2e 用例每次提交代码都要跑一遍开发效率会被拖垮。那这百分之五到百分之十的 e2e 用例应该覆盖什么我的原则是只覆盖核心业务路径和关键用户场景。比如电商系统里下单支付这条链路必须有 e2e 测试用户注册登录这条链路必须有搜索商品并查看详情这条链路必须有。但像“修改头像后裁剪图片”这种边缘功能就不一定需要 e2e 覆盖用集成测试或者手动测试就够了。profile1 这个配置通常就是用来定义“默认跑哪些 e2e 用例”的。你可以把最核心的那几十个用例放在 profile1 里每次 CI 都跑把更全面的用例放在 profile2 或 profile3 里每天定时跑一次或者发版前跑一次。这样既保证了核心路径的持续验证又不会让日常开发被拖慢。2.3 工具选型为什么我最终选了 Playwrighte2e 测试的工具这些年变化挺大的。早期大家用 Selenium后来 Puppeteer 火了一阵再后来 Cypress 成了很多前端团队的首选。我自己这几个工具都用过最后在新项目里稳定用 Playwright原因有几个。第一是自动等待机制。e2e 测试最头疼的问题之一就是“元素还没出现就去点它”。Selenium 需要你手动写 waitCypress 有重试机制但有时候重试逻辑不够透明。Playwright 的内置等待是我用过最顺手的它会自动等待元素可操作、可点击、可见大部分场景下你不需要写额外的等待代码。第二是多浏览器支持。Playwright 原生支持 Chromium、Firefox 和 WebKit而且 API 是一致的。你写一套用例可以配置在不同浏览器上跑。profile1 里我可以指定只跑 Chromiumprofile2 里跑全部三个浏览器切换起来很方便。第三是调试体验。Playwright 有 trace viewer可以把整个测试过程录下来每一步的 DOM 快照、网络请求、控制台日志都能回看。排查失败用例的时候这个功能能省掉大量时间。当然Cypress 的开发者体验也很好尤其是它的时间旅行调试。但 Cypress 在多标签页、多域名场景下限制比较多而 Playwright 在这方面更灵活。如果你的项目涉及跨域跳转或者多窗口操作Playwright 会更省心。2.4 profile1 的配置设计思路profile1 不是一个固定的标准它完全取决于你的项目怎么组织。但我在多个项目里总结出一套比较通用的配置结构你可以参考。通常我会在项目根目录下建一个e2e文件夹里面放几个东西playwright.config.ts是主配置文件profiles文件夹里放不同 profile 的覆盖配置tests文件夹里放用例fixtures文件夹里放测试数据和工具函数。profile1 的配置一般包含这些内容指定测试目录、指定浏览器类型、设置超时时间、配置重试次数、指定报告格式、配置 baseURL。如果是 CI 环境还会配置并行执行的 worker 数量。我习惯把 profile1 定义为“本地开发快速验证”用的配置。它的特点是只跑 Chromium、只跑核心用例、超时时间设短一点、失败不重试、报告直接输出到控制台。这样开发人员在本地改完代码跑一下 profile1几十秒就能知道核心路径有没有被破坏。而 CI 环境用的可能是 profile2它会跑全部用例、跑多个浏览器、失败重试两次、生成 HTML 报告并上传。发版前用的可能是 profile3它会在 profile2 的基础上加上性能指标采集和截图对比。这种分层的配置方式能让 e2e 测试在不同场景下发挥不同作用而不是一套配置打天下。3. 核心细节解析与实操要点3.1 用例设计怎么写出不容易挂的 e2e 测试e2e 测试最让人崩溃的就是“昨天还跑得好好的今天突然挂了”。很多时候不是代码有问题而是用例本身写得太脆弱。我总结了几条原则能大幅降低用例的维护成本。第一条原则用面向用户的定位器不用面向实现的定位器。什么意思比如你要点击一个登录按钮不要用div div:nth-child(3) button这种基于 DOM 结构的定位器也不要用.btn-primary这种基于样式的定位器。你应该用getByRole(button, { name: 登录 })或者getByText(登录)这种基于用户可见内容的定位器。这样即使前端重构了 DOM 结构、改了样式类名只要按钮上的文字没变用例就不会挂。第二条原则每个用例独立准备数据不依赖其他用例的执行结果。我见过很多团队为了省事让用例 A 创建数据用例 B 使用数据用例 C 删除数据。这种链式依赖一旦中间某个环节失败后面全挂而且排查起来非常痛苦。正确的做法是每个用例自己创建需要的数据跑完之后自己清理。虽然会多花一点时间但稳定性提升是值得的。第三条原则不要在用例里写死等待时间。sleep(3000)这种写法是 e2e 测试的毒药。网络快的时候浪费三秒网络慢的时候三秒不够还是挂。应该用工具提供的等待机制比如 Playwright 的waitForSelector、waitForResponse或者直接依赖它的自动等待。第四条原则一个用例只验证一个核心场景。不要把十个步骤塞进一个用例里。步骤越多失败的概率越大排查的时候也越难定位是哪一步出的问题。拆成多个小用例每个用例只走一条关键路径跑起来清晰维护起来也轻松。3.2 测试数据管理profile1 里怎么隔离数据e2e 测试的数据管理是个大坑。如果你用真实数据库测试数据和生产数据混在一起轻则查询结果被污染重则误删真实数据。如果你用 mock 数据又失去了 e2e 测试的意义。我的做法是为 e2e 测试单独准备一套数据库或 schema每次跑测试前重置。具体来说在 profile1 的配置里我会设置一个globalSetup脚本它在所有测试开始前执行负责清空测试库、插入基础数据、生成测试账号。然后每个用例内部再按需创建自己需要的数据。如果项目用的是容器化部署那就更简单了。每次跑 e2e 测试时启动一个独立的数据库容器跑完就销毁。这样数据完全隔离不会影响任何其他环境。对于 profile1 这种本地快速验证的配置我通常会用内存数据库或者 SQLite 来加速。因为本地开发时你不太关心数据库的兼容性只关心逻辑通不通。而 CI 环境的 profile2 会切换到和线上一致的数据库类型确保环境差异不会导致测试结果不一致。还有一个细节测试账号的权限要控制好。e2e 测试用的账号不要给管理员权限除非你专门在测管理员功能。普通用户账号能覆盖大部分场景而且更安全。如果确实需要测管理员功能单独建一个管理员测试账号并且限制它只能在测试环境使用。3.3 选择器策略让用例在 UI 改版后还能跑选择器是 e2e 测试里最常出问题的地方。前端改个样式、调个布局选择器就失效了。我见过一个团队每次前端发版后都要花半天时间修 e2e 用例的选择器效率极低。解决这个问题的根本办法是和前端团队约定一套测试专用的属性。比如在需要被 e2e 测试操作的元素上加上>// e2e/profiles/profile1.config.ts import { defineConfig } from playwright/test; import baseConfig from ../playwright.config; export default defineConfig({ ...baseConfig, testDir: ../tests/core, timeout: 30000, retries: 0, workers: 2, use: { ...baseConfig.use, browserName: chromium, headless: true, baseURL: http://localhost:3000, trace: retain-on-failure, }, reporter: [[list]], });这个配置的含义是只跑tests/core目录下的核心用例超时 30 秒失败不重试用两个并行 worker只跑 Chromium无头模式失败时保留 trace 文件报告直接输出到控制台。第四步在package.json里加脚本{ scripts: { e2e:profile1: playwright test --confige2e/profiles/profile1.config.ts, e2e:profile2: playwright test --confige2e/profiles/profile2.config.ts, e2e:profile3: playwright test --confige2e/profiles/profile3.config.ts } }这样开发人员在本地只需要跑npm run e2e:profile1就能快速验证核心路径。4.2 编写第一个核心用例登录流程登录是几乎所有系统都有的功能也是 e2e 测试最典型的入门用例。我以登录为例展示一个完整的用例怎么写。// e2e/tests/core/login.spec.ts import { test, expect } from playwright/test; test.describe(登录流程, () { test.beforeEach(async ({ page }) { await page.goto(/login); }); test(使用正确的用户名和密码可以登录成功, async ({ page }) { await page.getByLabel(用户名).fill(testuser); await page.getByLabel(密码).fill(Test123456); await page.getByRole(button, { name: 登录 }).click(); await expect(page).toHaveURL(/dashboard); await expect(page.getByText(欢迎回来)).toBeVisible(); }); test(使用错误的密码会提示错误信息, async ({ page }) { await page.getByLabel(用户名).fill(testuser); await page.getByLabel(密码).fill(wrongpassword); await page.getByRole(button, { name: 登录 }).click(); await expect(page.getByText(用户名或密码错误)).toBeVisible(); await expect(page).toHaveURL(/login); }); test(用户名为空时登录按钮不可用或提示必填, async ({ page }) { await page.getByLabel(密码).fill(Test123456); await page.getByRole(button, { name: 登录 }).click(); await expect(page.getByText(请输入用户名)).toBeVisible(); }); });这个用例里有几个细节值得说。第一我用了getByLabel来定位输入框这要求前端表单的 label 和 input 正确关联。如果前端没做关联可以用getByPlaceholder或者getByTestId替代。第二我用了toHaveURL来验证跳转这比检查页面上有没有某个元素更可靠。第三错误提示的断言用了toBeVisible确保提示真的展示出来了而不是仅仅存在于 DOM 里但被隐藏了。4.3 处理异步和网络请求等待策略详解e2e 测试里最复杂的部分就是处理异步。页面加载、接口请求、动画过渡、数据渲染这些都是异步的。如果等待策略不对用例就会时好时坏。Playwright 的自动等待能覆盖大部分场景但有些情况还是需要手动处理。我举几个典型场景。场景一点击按钮后触发了一个接口请求需要等请求完成后再断言。这时候可以用waitForResponseconst responsePromise page.waitForResponse( (response) response.url().includes(/api/orders) response.status() 200 ); await page.getByRole(button, { name: 提交订单 }).click(); await responsePromise; await expect(page.getByText(订单提交成功)).toBeVisible();注意这里先创建responsePromise再执行点击顺序不能反。如果先点击再等待可能请求已经完成了你就等不到了。场景二页面有多个异步加载的模块需要等所有模块都加载完。可以用waitForLoadStateawait page.waitForLoadState(networkidle);但networkidle不是万能的如果页面有轮询请求或者 WebSocket 长连接networkidle可能永远等不到。这时候应该用更具体的等待条件比如等待某个关键元素出现。场景三元素存在但不可点击比如被遮罩层挡住了。Playwright 的click会自动等待元素可点击但如果遮罩层一直不消失就会超时。这时候需要先处理遮罩层await page.getByRole(button, { name: 关闭弹窗 }).click(); await page.getByRole(button, { name: 提交 }).click();如果遮罩层是自动消失的可以用waitForSelector等它消失await page.waitForSelector(.loading-mask, { state: hidden });4.4 并行执行与重试profile1 和 profile2 的差异profile1 我通常设置workers: 2retries: 0。因为本地开发时你希望快速得到反馈失败了就去看问题不需要重试。而且本地机器资源有限开太多 worker 反而会互相干扰。profile2 用于 CI 环境我会设置workers: 4或更高取决于 CI 机器的配置retries: 2。CI 环境通常比本地稳定但偶尔也会有网络抖动或者资源竞争导致的偶发失败。重试两次能过滤掉大部分偶发问题同时如果重试后还是失败那就说明确实有 bug。但重试有个副作用它会让测试运行时间变长。如果一个用例本来跑 10 秒失败后重试两次就变成了 30 秒。所以重试次数不能设太多两次足够了。而且我建议在报告里明确标记哪些用例是重试后才通过的这样你能知道哪些用例不稳定后续去优化它们。并行执行也有坑。如果多个用例同时操作同一份数据就会互相干扰。比如两个用例同时创建订单订单号可能冲突。解决办法是每个用例用独立的数据比如用时间戳或者随机字符串作为订单号的一部分。或者用test.describe.serial让同一组用例串行执行但这样会降低速度只适合确实有依赖关系的用例。4.5 集成到 CI/CD让 e2e 测试自动跑起来e2e 测试如果不集成到 CI/CD 里很容易被遗忘。我的做法是在代码提交和合并请求这两个环节都加上 e2e 测试。提交环节跑 profile1只跑核心用例快速反馈。如果核心路径被破坏了开发者立刻就能知道。合并请求环节跑 profile2跑全部用例确保没有遗漏。发版前跑 profile3加上视觉对比和性能检查。在 GitHub Actions 里配置大概是这样name: E2E Tests on: push: branches: [main, develop] pull_request: branches: [main] jobs: e2e-profile1: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-nodev4 with: node-version: 20 - run: npm ci - run: npx playwright install --with-deps chromium - run: npm run e2e:profile1 - uses: actions/upload-artifactv4 if: failure() with: name: playwright-trace path: test-results/几个关键点npx playwright install --with-deps chromium只安装 Chromium比安装全部浏览器快很多。if: failure()确保只在失败时上传 trace节省存储空间。test-results目录里会有失败用例的截图、视频和 trace 文件排查问题时非常有用。如果 CI 环境访问不了测试环境可以用webServer配置让 Playwright 自动启动本地服务webServer: { command: npm run start:test, port: 3000, reuseExistingServer: !process.env.CI, timeout: 120000, },这样 Playwright 会先启动服务等端口就绪后再跑测试跑完自动关闭服务。5. 常见问题与排查技巧实录5.1 用例不稳定偶发失败怎么查e2e 测试最让人头疼的就是偶发失败。同一个用例跑十次可能挂一次而且每次挂的地方还不一样。这种问题排查起来非常耗时但也不是没有章法。第一步收集足够的现场信息。Playwright 的 trace 功能是排查偶发失败的神器。在配置里设置trace: retain-on-failure失败时会把整个测试过程录下来。你用npx playwright show-trace test-results/xxx/trace.zip打开可以看到每一步的 DOM 快照、网络请求、控制台日志。很多时候你一看 trace 就明白问题出在哪了。第二步检查等待逻辑。偶发失败十有八九是等待不够。比如点击按钮后接口还没返回就去断言成功提示网络快的时候能过网络慢的时候就挂。解决办法是用waitForResponse或者waitForSelector替代固定等待。第三步检查数据隔离。如果多个用例并行执行可能会互相干扰。比如两个用例同时用同一个账号登录后登录的会把先登录的踢下线。解决办法是每个用例用独立账号或者用test.describe.serial让它们串行。第四步检查环境差异。本地能过 CI 挂可能是环境配置不同。比如本地用了 mock 数据CI 连了真实数据库本地时区是 UTC8CI 是 UTC。这些差异都可能导致用例行为不一致。我整理了一个常见偶发失败的原因速查表现象可能原因排查方法解决方案元素找不到页面还没渲染完查看 trace 中的 DOM 快照用 waitForSelector 或自动等待点击无效元素被遮挡或不可点击检查元素是否可见、是否被覆盖先关闭遮罩层或滚动到元素位置断言失败但实际正确断言时机太早查看 trace 中的断言时刻用 waitForResponse 等待接口完成登录状态丢失多个用例共用账号检查用例是否并行执行每个用例独立账号或串行执行只在 CI 失败环境配置不同对比本地和 CI 的环境变量统一环境配置或加环境判断5.2 选择器失效UI 改版后怎么快速修复UI 改版导致选择器失效是 e2e 测试维护成本的主要来源。要减少这种痛苦核心是和前端团队建立约定。我在团队里推行的做法是所有需要被 e2e 测试操作的元素必须加>export const selectors { login: { usernameInput: username-input, passwordInput: password-input, submitButton: login-submit, errorMessage: login-error, }, order: { createButton: order-create, submitButton: order-submit, successMessage: order-success, }, };这样 UI 改版时你只需要改selectors.ts一个文件所有用例自动适配。5.3 测试数据污染怎么保证每次跑都是干净环境测试数据污染是另一个常见问题。跑了几轮测试后数据库里堆了一堆测试数据查询结果被污染用例开始随机失败。我的解决方案是每次跑测试前重置测试数据库。在globalSetup里执行数据库清理和基础数据插入// e2e/global-setup.ts import { execSync } from child_process; async function globalSetup() { execSync(npm run db:reset:test, { stdio: inherit }); execSync(npm run db:seed:test, { stdio: inherit }); } export default globalSetup;db:reset:test负责清空测试库db:seed:test负责插入基础数据比如测试账号、基础配置。这样每次跑测试都是从一个已知的干净状态开始。如果项目用的是容器化数据库那就更简单了。在 CI 配置里每次跑 e2e 测试时启动一个新的数据库容器跑完销毁。本地开发时可以用 Docker Compose 快速起一个测试数据库。还有一个细节测试数据的命名要有规律。比如所有测试账号都以e2e_开头所有测试订单都以E2E-开头。这样即使清理不彻底你也能通过命名规则识别出哪些是测试数据手动清理时不会误删真实数据。5.4 超时问题怎么合理设置超时时间超时设置太短用例容易误报失败超时设置太长失败时等待时间太久拖慢整体速度。我的经验是分层设置超时。全局超时设置在配置文件里我通常设 30 秒。这个时间足够大部分用例完成又不会让失败用例等太久。对于特别复杂的用例比如涉及多个页面跳转和大量数据加载的可以在用例级别单独设置更长的超时test(复杂下单流程, async ({ page }) { test.setTimeout(60000); // ... });对于断言级别的超时Playwright 默认是 5 秒。如果某个断言需要更长时间可以单独设置await expect(page.getByText(处理完成)).toBeVisible({ timeout: 15000 });但要注意不要用超时来掩盖问题。如果一个用例经常超时说明它本身有问题要么是等待逻辑不对要么是性能太差。应该去优化用例或者优化系统而不是简单地把超时时间调大。5.5 报告与日志怎么快速定位失败原因e2e 测试失败后快速定位原因比什么都重要。我通常会在三个地方收集信息。第一是控制台输出。Playwright 的 list reporter 会在控制台显示每个用例的执行结果和失败原因。如果失败原因是断言失败它会显示期望值和实际值。第二是HTML 报告。profile2 和 profile3 我会配置 HTML reporter生成一个可视化的报告页面。报告里可以看到每个用例的执行时间、失败截图、错误堆栈。对于团队协作来说HTML 报告比控制台输出更友好。第三是trace 文件。前面说过trace 是排查偶发失败的神器。我建议在 CI 环境里失败时自动上传 trace 文件作为 artifact方便后续下载分析。另外在用例里加日志也很有帮助。Playwright 的page.on(console)可以捕获浏览器控制台的日志page.on(requestfailed)可以捕获失败的请求。把这些日志输出到测试报告里排查问题时能省很多时间。test.beforeEach(async ({ page }) { page.on(console, (msg) { if (msg.type() error) { console.log(浏览器错误: ${msg.text()}); } }); page.on(requestfailed, (request) { console.log(请求失败: ${request.url()} - ${request.failure()?.errorText}); }); });这个配置能帮你抓住很多隐藏的问题比如前端报错、接口 404、资源加载失败等。6. 一些实操心得和避坑建议6.1 不要追求百分之百的 e2e 覆盖率我见过一些团队试图用 e2e 测试覆盖所有功能结果用例数量膨胀到几百个跑一轮要一个小时维护成本极高最后大家都不愿意跑e2e 测试形同虚设。e2e 测试的定位是验证核心用户路径不是替代单元测试和集成测试。把覆盖率控制在合理范围内让 e2e 测试保持快速、稳定、可信比追求覆盖率数字重要得多。6.2 用例要能独立运行每个 e2e 用例都应该能单独运行不依赖其他用例的执行结果。这样你才能在调试时只跑一个用例快速验证问题是否修复。如果用例之间有依赖调试起来会非常痛苦。实现独立运行的关键是数据自管理。每个用例在beforeEach里创建自己需要的数据在afterEach里清理。虽然会多写一些代码但换来的灵活性和稳定性是值得的。6.3 定期清理和优化用例e2e 用例不是写完就一劳永逸的。随着产品迭代有些用例可能已经过时了有些用例可能变得不稳定了。我建议每个月花一点时间 review 一下 e2e 用例删掉过时的修复不稳定的优化运行慢的。一个健康的 e2e 测试套件应该是跑得快、挂得少、修得快。如果发现某个用例经常挂要么修复它要么删掉它。留着不稳定的用例只会消耗团队对 e2e 测试的信任。6.4 profile 配置要跟着项目走profile1、profile2、profile3 不是固定的你可以根据项目需要增减。比如小项目可能只需要 profile1 和 profile2大项目可能需要 profile4 来跑跨浏览器兼容性测试profile5 来跑移动端适配测试。关键是让每个 profile 有明确的用途不要为了配置而配置。profile 太多会导致维护成本上升太少又无法覆盖不同场景。找到适合你团队的平衡点。6.5 把 e2e 测试当成产品来维护最后一条心得e2e 测试代码也是代码需要像产品代码一样维护。它需要良好的结构、清晰的命名、适当的抽象、定期的重构。如果你把 e2e 测试当成一次性脚本随便写写那它很快就会变成技术债。我在团队里推行的一个做法是e2e 测试代码和产品代码走同样的 code review 流程。新加的用例要 review修改的用例也要 review。这样能保证用例质量也能让团队成员互相学习。这个内容后续还可以这样扩展把 e2e 测试和性能监控结合起来在核心路径上采集加载时间、接口响应时间等指标建立性能基线一旦性能退化就自动告警。这样 e2e 测试就不只是功能验证还能成为性能保障的一部分。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑