我们从Cypress转移到Playwright的测试转变

在我們關於extensive-react-boilerplate更新的文章中,我們提到了我們將端到端測試從Cypress遷移到Playwright。現在,讓我們深入研究這一變化。

在寫自動測試時,我們覆蓋的功能很少,使用Cypress時並未遇到顯著的限制。然而,我們還是決定轉向Playwright,原因是多種多樣。我們想要探索微軟創建的框架,並理解為什麼它正在獲得popularity。此外,與我們添加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 外的其他程序語言,以及得到了 Microsoft 這家大型企業的支持。

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