獨孤九劍的「破槍式」,破解長槍、大戟、蛇矛、齊眉棍、狼牙棒、白蠟桿、禪杖、方便鏟等長兵器。我今天想來介紹一種常用的 Pattern,並且能夠讓測試案例更為穩定的一種方法,這個設計模式,叫做「Loadable Component」,概念很簡單就是「確保頁面真的載入好了,才繼續下一步」。
在測試設計模式(Design Pattern)中,Loadable Component 是一種專門用來確保頁面或元件在測試執行前已正確載入的設計模式。它常被用來解決測試程式中「元素還沒準備好就開始操作」所導致的 flakiness(不穩定測試)。
由於每個頁面 (Page Object) 或是元件(Component) 載入的時間都不一致,並且每個頁面裡的元件載入的時間也不一樣。舉例:登入頁面載入的時候,需要載入使用者名稱輸入元件、密碼輸入元件,登入按鈕等等,如果我們沒有等到全部元件都載入完畢再開始測試,可能會導致因為程式找不到某個元素,而讓測試案例失敗,而導致測試不穩定。每個頁面(Page Object)或元件(Component)都要有一個「載入完成方法」,用來檢查該頁面或元件是否已經可以被測試程式碼互動。
// pages/LoginPage.ts
import { Page, expect } from '@playwright/test';
export class LoginPage {
constructor(private page: Page) {}
private usernameField = this.page.getByTestId('login-username');
private passwordField = this.page.getByTestId('login-password');
private submitButton = this.page.getByTestId('login-submit');
private loginHeading = this.page.getByRole('heading', { name: '登入' });
async waitUntilLoaded() {
await expect(this.loginHeading).toBeVisible({ timeout: 5000 });
await expect(this.usernameField).toBeVisible();
await expect(this.passwordField).toBeVisible();
}
async isLoaded(): Promise<boolean> {
return await this.loginHeading.isVisible();
}
async login(username: string, password: string) {
await this.usernameField.fill(username);
await this.passwordField.fill(password);
await this.submitButton.click();
}
}
// tests/login.spec.ts
import { test } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
test('Login with valid credentials', async ({ page }) => {
const loginPage = new LoginPage(page);
await page.goto('https://your-app.example.com/login');
await loginPage.waitUntilLoaded(); // Loadable Component 核心步驟
await loginPage.login('user01', 'pass123');
// 進一步驗證登入後狀態
await page.waitForURL('**/home');
});
我們可以將 Loadable Component 視為 POM 的延伸版,在 POM 的基礎上面增加檢查是否「載入完成」的函式,透過 Playwright 的自動等待(Auto-Waiting) 並且搭配顯式驗證,可以有效將低因為測試程式碼執行太快,導致測試案例失敗的機率。
今天的設計模式,叫做 Loadable Component。是為了解決了測試最常遇到的痛點之一:測試不穩定(flakiness)。這個模式的概念很簡單,就是要確保頁面或元件都已經載入好了,我們才繼續執行下一步。Loadable Component 就像是每個頁面或元件的「準備確認函式」。我們在每個頁面物件(Page Object)裡,都加入一個方法,像是 waitUntilLoaded(),它會去檢查頁面上的關鍵元素是不是都已經出現了。簡單的說,確認元素都載入完成,再繼續測試,這樣能夠檢查測試因為元素不存在或載入時間比較慢而失敗。