在我們關於extensive-react-boilerplate更新的文章中,我們提到了我們將端到端測試從Cypress遷移到Playwright。現在,讓我們深入研究這一變化。
在寫自動測試時,我們覆蓋的功能很少,使用Cypress時並未遇到顯著的限制。然而,我們還是決定轉向Playwright,原因是多種多樣。我們想要探索微軟創建的框架,並理解為什麼它正在獲得popularity。此外,與我們添加MongoDB支持的情況相似,我們從社區和同事那裡收到了開始基於 boilerplate 並使用Playwright測試的請求。
當我們開始遷移測試的過程時,我們意識到測試的量是微不足道的。因此,我們決定手動重寫測試,以便更詳細地熟悉新框架。
熟悉新框架
首先,我們從討論 文档開始。我們可以自信地說,Cypress的 文档超过了Playwright。Cypress的文档非常詳細,並包含許多示例和教程。在GitHub上還有一個整個項目,包含可以 在典型網站上執行的一切行為的示例。此外,Cypress的社區規模也比Playwright大。雖然有經驗的開發者可能對Playwright的文档中提供的信息感到滿意,但經驗較少的開發者可能會發現學習Cypress更有趣。
移步到設定配置文件。我們在兩個框架之間找不到重大差異。我們只需要配置超時和基本URL。我們也探索了Playwright在這一方面提供的一些新功能,例如:
- 為每個測試設定超時,包括測試和Before/After挂钩:
// playwright.config.ts
export default defineConfig({
...
timeout: 2 * 60 * 1000,
...
});
- 支持在基於Apple Safari的WebKit上進行測試,而Cypress則缺乏這種支持
Playwright還能夠在運行測試之前為您的項目啟動本地開發服務器,這可以通過使用webServer
參數輕鬆實現。
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代碼示例:
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的:
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