E2E:防止对 UI 的过度耦合

发布: (2026年1月19日 GMT+8 07:01)
3 min read
原文: Dev.to

Source: Dev.to

虽然有很多优秀的 e2e 框架,例如 Playwright,但工具本身无法防止误用。

实现细节 vs. 行为

一个非常常见的错误是关注实现细节:

await page.goto('/signup');
await expect(page.locator('.btn-signup.primary')).toBeVisible();

这并不一定在所有情况下都是坏事,但它把测试耦合到了前端的样式决策上。任何 CSS 重构或结构调整都会导致与功能无关的测试失败。

相反,应该关注功能本身:

await page.goto('/signup');
/* 这里可能还有其他测试,例如填写一些输入框 */
await page.click('#submit-signup');

嵌套元素 vs. 弹性测试

依赖深层 CSS 选择器通常不是理想的做法:

await page.locator(
  '#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input'
).click();

Source: Locate by CSS or XPath - Playwright

Playwright 提供了丰富的 API,但这并不意味着你应该使用脆弱的选择器。CSS 和 XPath 并不推荐使用,因为 DOM 可能会变化,导致测试不具弹性。应优先使用能够反映用户感知页面的定位方式,例如角色定位器或显式的测试 ID。

缺少 fixture

通过缓慢的 UI 交互创建所有内容会让 e2e 测试变得非常慢。可复用的 fixture 能确保一致性并防止重复的设置逻辑:

// ./tests/fixtures/myFixture.js
const test = baseTest.extend(/* your code */);
// ./tests/pages/mypage.spec.js
import { test } from '../fixtures/myFixture';

test('should do something good', async ({ target }) => {
  /* your code */
});

Source: Fixtures - Playwright

防御性过度测试

你可能已经有了单元测试(纯业务逻辑)、集成测试以及其他层级的测试,在此之上才是 e2e 测试。e2e 测试应聚焦真实的用户体验,而不是重新评估低层测试已经覆盖的内容。确保各层相互补充而非冗余,以避免重复工作、自动化变慢以及成本上升。

如何做得更好

避免上述不良实践,遵循良好的设计原则:

  • 为每次测试运行创建全新的数据。
  • 不要依赖之前的结果;保持测试相互独立。
  • 将冗长的测试拆分为更小、更聚焦的测试。
  • 只测试用户能看到的内容(例如成功提示,而不是 CSS 类)。

编写可维护的测试可能在前期需要更多时间,但脆弱的 e2e 测试所带来的成本可能更为显著。

Back to Blog

相关文章

阅读更多 »