首页 纸飞机TG账号批发老号购买内容详情

Playwright 官方推荐的 Fixture 模式,为什么大厂架构师却在偷偷弃用?

2026-03-15 4 纸飞机账号购买

01. 引言:被“神化”的 Fixture

于自动化测试这个圈子当中,Playwright 的现身差不多算是那种具有极大优势处于高位狠狠打击低位的情况。并且呢,它官方文档最为值得骄傲自豪的特性,那便是 Fixtures(固件)了。

官方告知我们,忘掉那些,手动初始化Pages Object的噜苏代码,把它交予Fixture之处,你会取得最为优雅的依赖注入。

刚开始看的时候,的确是这样的情况。然而,一旦你踏入腾讯、阿里或者字节跳动这类大厂那些繁杂的业务线,当面对着有着1000多个页面对象、5000多个测试用例这么一个超大型项目的时候你就会发觉,当初认为“优雅”的Fixture,正暗暗地演变成项目的“维护噩梦”。

到底是因何缘故,众多架构师于后期之时,挑选了回归至“懒加载(Lazy Approach)”这一方式呢?这一篇文章会引领着你,去剖析其中所蕴含的工程化真相所在。

02. Fixture 模式:优雅的代价是“黑盒”

首先,我们得认可 Fixture 具备强大之处,它在本质上属于一种依赖注入这种方式。

// 官方推崇的模式:声明式注入
export const test = base.extend({
  userPage: async ({ page }, use) => {
    await use(new UserPage(page));
  },
  orderPage: async ({ page }, use) => {
    await use(new OrderPage(page));
  },
});
// 在用例中使用:看起来非常干净
test('下单流程', async ({ userPage, orderPage }) => {
  await userPage.login();
  await orderPage.create();
});

为什么它受宠?为什么大厂架构师开始皱眉?

当项目规模爆炸时,Fixture 会带来 “注册表膨胀”。

源头难以追踪,当你把 10 个 Fixture 解析出来,想要转到某个 Page Object 的定义处,IDE 有时会在复杂的 extend 链条里迷失方向。初始化逻辑具有强制性,即便 Playwright 宣称是按需加载,然而在大型工程当中,Fixture 的层层嵌套的依赖关系,常常会致使为了使用一个 A,不得不触发 B 和 C 的 Setup,从而增加了不必要的隐性复杂化程度。03.懒加载模式:回归“显式”的影响力。

在主张方面,懒加载(Lazy Approach)秉持这样的观点:仅当那一刻,也就是用到 Page Object 的那个时刻,才会去进行实例化它这个行为。

// 架构师偏爱的模式:显式实例化
test('下单流程', async ({ page }) => {
  const userPage = new UserPage(page);
  await userPage.login();
  // 只有登录成功,才加载订单页
  const orderPage = new OrderPage(page);
  await orderPage.create();
});

它为何于大型项目里更具稳健性呢?有着堪称完美的类型推导,这表现为比如说 new UserPage(page) 属于标准的 TypeScript 行为,在 IDE 之中,跳转、重构以及属性提示向来都是瞬间便能回复,不会由于复杂的类型注入遭遇像“卡死”这类情况。并且具备零副作用,不存在隐藏的 extend,也没有复杂的配置文件,每一个用例所使用到的内容以及初始化的内容均清晰明了、一目了然。对于条件分支而言是友好的:要是在你的测试逻辑当中存在着一个 if (discountAvailable) 的情况,那么懒加载能够使得你仅仅是在条件得以成立的时候才去初始化“优惠券页面”这个对象,进而节省内存以及潜在的初始化所耗费的时间。04. 进行深度对比:从工程化的视角来看的有着博弈维度的 Fixture (依赖注入),还有着 Lazy Approach (显式初始化)。

可读性

极高(脚本像自然语言)

中(可见初始化代码)

可维护性

随规模增长迅速下降

随规模增长保持线性

IDE 支持

偶尔失效,跳转复杂

完美支持,原生体验

依赖关系

隐式(在配置文件里)

显式(在测试用例里)

上手门槛

需要理解 Playwright 注入机制

只要会写 PO 类即可

05. 进阶的方案,架构师所拥有的“秘密武器”,那便是Container模式。

要是既存有对Fixture简洁的念想,又怀有对懒加载稳健的期望,大厂架构师一般会去封装一个Page容器,或者App对象。

代码实现:

// 这是一个“页面工厂”容器
export class App {
  constructor(private readonly page: Page) {}
  // 使用 Getter 实现真正的懒加载
  get loginPage() { return new LoginPage(this.page); }
  get cartPage() { return new CartPage(this.page); }
  get paymentPage() { return new PaymentPage(this.page); }
}
// 在 Fixture 中只注入这一个 App 容器
export const test = base.extend<{ app: App }>({
  app: async ({ page }, use) => {
    await use(new App(page));
  },
});
// 最终的用例:兼顾简洁与控制感
test('完整购物流', async ({ app }) => {
  await app.loginPage.goto();
  await app.cartPage.addItem('MacBook');
  await app.paymentPage.pay();
});

这种模式的妙处在于:

06. 总结:你该如何选择?

官方之所以推荐Fixture,是由于它在中小型项目以及演示当中能够给予极致的“代码美感”。然而在大厂的生产环境里,“稳定”连同“可维护性”始终是高于“美感”的。

相关标签: # Playwright # Fixture模式 # 懒加载 # 大厂架构师 # 工程化