我们从Cypress转向Playwright进行测试

在我们的关于extensive-react-boilerplate更新的文章中,我们提到了我们将e2e-testing从Cypress迁移到了Playwright。现在,让我们更深入地探讨一下这个变化。

在编写自动化测试时,我们的功能覆盖范围很小,使用Cypress并没有遇到重大限制。然而,我们还是决定关注Playwright,原因有几个。我们想探索由微软创建的框架,并了解它为什么越来越受欢迎。另外,与添加MongoDB支持的情况类似,我们从社区和同事那里收到了基于 boilerplate 和 Playwright 测试启动项目的请求。

当我们开始迁移测试时,我们意识到测试量很小。因此,我们决定手动重写测试,以便更详细地了解新框架。

熟悉新框架

首先,我们从讨论文档开始。我们可以自信地说,Cypress的文档超过了Playwright。Cypress的文档非常详细,包含了许多例子和教程。在GitHub上还有一个完整的项目,包含了每个典型网站上可以执行的每个动作的示例。此外,Cypress的社区规模也大于Playwright。尽管经验丰富的开发者可能对Playwright文档中提供的信息感到满意,但经验较少的开发者可能会发现学习Cypress更有趣。

接下来是设置配置文件。我们没有发现两个框架之间有明显的不同。我们只需配置超时和基础 URL。我们还探索了 Playwright 在这方面提供的一些新功能,例如:

  • 为每个测试设置超时,包括测试和 Before/After 钩子:
TypeScript

 

// playwright.config.ts
export default defineConfig({
...
  timeout: 2 * 60 * 1000,
...
});

  • 支持在基于 Apple Safari 的 WebKit 上进行测试,而 Cypress 缺乏此类支持

Playwright 还具有在运行测试之前与您的项目一起启动本地开发服务器的功能,这可以使用 webServer 参数轻松实现。

TypeScript

 

  webServer: {
    command: process.env.CI
      ? "npm run build:e2e && npm run start"
      : "npm run dev",
    url: "http://127.0.0.1:3000",
    reuseExistingServer: !process.env.CI,
  },

接下来,我们编写第一个测试。这两个框架在语法上的差异非常明显。Cypress 使用可链式语法并拥有自己的异步实现,而 Playwright 支持 ECMAScript 2015 标准 (ES6),并为异步函数提供方便的 async/await 结构。

以下是 Playwright 代码示例:

TypeScript

 

  test("should be successful open page and check data is displayed", async ({
    page,
  }) => {
    await page.getByTestId("profile-menu-item").click();
    await page.getByTestId("user-profile").click();
    await page.waitForURL(/\/profile/);
    await expect(page.getByTestId("user-name")).toHaveText(
      `${firstName} ${lastName}`
    );
    await expect(page.getByTestId("user-email")).toHaveText(email, {
      ignoreCase: true,
    });
    await page.getByTestId("edit-profile").click();
    await page.waitForURL(/\/profile\/edit/);
    await expect(page.getByTestId("first-name").locator("input")).toHaveValue(
      firstName
    );
    await expect(page.getByTestId("last-name").locator("input")).toHaveValue(
      lastName
    )

以下是 Cypress 代码示例:

JavaScript

 

  it("should be successful open page and check data is displayed", () => {
    cy.getBySel("PersonIcon").click();
    cy.getBySel("user-profile").click();
    cy.location("pathname").should("include", "/profile");
    cy.getBySel("user-name").should("contain.text", firstName + " " + lastName);
    cy.getBySel("user-email").should("contain.text", email);
    cy.getBySel("edit-profile").click();
    cy.location("pathname").should("include", "/profile/edit");
    cy.get('[data-testid="first-name"] input').should("contain.value", firstName);
    cy.get('[data-testid="last-name"] input').should("contain.value", lastName);
  });

框架比较

在运行测试时,我们注意到框架之间的架构差异。

  • Cypress 在浏览器中执行命令,这使它可以轻松访问 DOM、本地存储和窗口对象等重要组件。另一方面,Playwright 使用客户端-服务器架构,并通过 WebSocket 连接与浏览器通信。
  • 在重写所有测试后,我们运行了它们并观察到,Playwright 默认情况下是并行运行测试的,免费提供这一功能。相比之下,Cypress 仅对不同机器进行并行化,并且这是一个付费功能。
  • 在两个框架中运行相同的测试显示,Playwright 比 Cypress 更快地完成测试。

我们进行了测试,发现 Playwright 用 2.7 分钟完成了测试:

而 Cypress 需要 3.82 分钟,显示出 Playwright 有利于显著的时间差异。

结论

考虑到所有上述要点,人们可能会想知道我们为什么决定更换框架。尽管我们当时没有看到显著的好处,但我们考虑了项目的未来和可能会建立在 bcboilerplates 生态系统模板之上的潜在项目。从这种角度来看,Playwright 似乎比 Cypress 更有前途,因为它具有测试的并行化、更高的速度、测试移动应用程序的可能性、可以使用除了 JS 和 TS 之外的编程语言,以及像微软这样的大公司的支持。

Source:
https://dzone.com/articles/our-shift-from-cypress-to-playwright-in-testing