Playwright TypeScript cho người mới: cài đặt và viết test đầu tiên
Playwright là thư viện test tự động của Microsoft, miễn phí, chạy được trên Chromium, Firefox và WebKit. Điểm mạnh với người mới là tự chờ phần tử (auto-wait), báo cáo HTML có sẵn và công cụ ghi thao tác thành code. Bài này đi từ cài đặt đến một test đăng nhập có cấu trúc gọn.
1. Cài đặt
Cần Node.js 20 trở lên. Mở terminal trong một thư mục trống:
npm init playwright@latest
Chọn TypeScript, thư mục test là tests, đồng ý cài trình duyệt. Sau đó chạy thử:
npx playwright test
npx playwright show-report
2. Test đầu tiên
Ví dụ dùng trang demo công khai saucedemo.com. Tạo file tests/login.spec.ts:
import { test, expect } from '@playwright/test';
test('TC-LOGIN-01 đăng nhập thành công', async ({ page }) => {
await page.goto('https://www.saucedemo.com');
await page.getByPlaceholder('Username').fill('standard_user');
await page.getByPlaceholder('Password').fill('secret_sauce');
await page.getByRole('button', { name: 'Login' }).click();
await expect(page.locator('.title')).toHaveText('Products');
});
Không có dòng chờ nào: fill, click và expect đều tự chờ phần tử sẵn sàng.
3. Chọn locator thế nào
Thứ tự ưu tiên nên dùng: getByRole, getByLabel, getByPlaceholder, getByText, thuộc tính test riêng như data-test. XPath dài theo cấu trúc DOM dễ vỡ khi giao diện đổi. Nếu chưa biết viết locator, chạy npx playwright codegen https://www.saucedemo.com để ghi lại thao tác rồi chỉnh lại code.
4. Page Object Model
Khi có nhiều test cùng dùng trang đăng nhập, gom locator và thao tác vào một class:
// pages/LoginPage.ts
import { Page } from '@playwright/test';
export class LoginPage {
constructor(private readonly page: Page) {}
async goto() { await this.page.goto('/'); }
async login(user: string, pass: string) {
await this.page.getByPlaceholder('Username').fill(user);
await this.page.getByPlaceholder('Password').fill(pass);
await this.page.getByRole('button', { name: 'Login' }).click();
}
}
Khi giao diện đổi, chỉ cần sửa một chỗ. Đặt baseURL trong playwright.config.ts để goto('/') chạy được trên nhiều môi trường.
5. Test nhiều bộ dữ liệu
const cases = [
{ id: 'TC-LOGIN-02', user: 'locked_out_user', msg: 'locked out' },
{ id: 'TC-LOGIN-03', user: '', msg: 'Username is required' },
];
for (const c of cases) {
test(`${c.id} báo lỗi`, async ({ page }) => {
const login = new LoginPage(page);
await login.goto();
await login.login(c.user, 'secret_sauce');
await expect(page.locator('[data-test="error"]')).toContainText(c.msg);
});
}
Đặt mã TC trong tên test giống file Excel giúp đối chiếu kết quả dễ dàng. Xem thêm cách viết test case bằng Excel.
6. Test API không cần Postman
test('TC-API-01 GET posts', async ({ request }) => {
const res = await request.get('https://jsonplaceholder.typicode.com/posts');
expect(res.status()).toBe(200);
});
Lỗi người mới hay gặp
- Dùng
page.waitForTimeout(3000): test chậm và vẫn chập chờn. Hãy dùngexpectđể chờ đúng điều kiện. - Quên
await: test kết thúc trước khi thao tác chạy xong. - Các test phụ thuộc nhau (test sau cần dữ liệu test trước tạo ra). Mỗi test nên tự chuẩn bị dữ liệu.
- Locator khớp nhiều phần tử: Playwright báo lỗi strict mode. Thu hẹp bằng
filterhoặc locator cụ thể hơn.
Bước tiếp theo
Thêm fixture để test nhận sẵn page object, cấu hình chụp ảnh và quay video khi fail, rồi đưa lên GitHub Actions để test chạy mỗi lần push code. Bộ QA Kit có sẵn một repo đã cấu hình các phần này, chạy được ngay với 8 test mẫu.