Tại sao tôi chuyển từ Selenium sang Playwright?
Tháng 9 năm ngoái, team tôi quyết định migrate từ Selenium sang Playwright. Lý do rất đơn giản: mấy anh dev cứ than rằng test Selenium của bọn tôi “flaky” — nghĩa là hôm nay pass, ngày mai fail mà không rõ lý do. CI/CD pipeline trở thành nỗi ám ảnh. Deploy thứ Sáu là cả team run sợ.
Tôi được giao nhiệm vụ học Playwright và viết lại bộ test. Deadline: 6 tuần. Kinh nghiệm automation trước đó của tôi: 2 năm với Selenium, khá tự tin. Tôi nghĩ: “Playwright thì khác gì mấy đâu, chắc học nhanh thôi.”
Tôi đã sai.
❌ Sai lầm #1
Tôi nhảy thẳng vào viết test mà không đọc docs. Cài xong, mở file example lên, thấy quen quen rồi bắt đầu code ngay. Kết quả: 3 ngày sau phải xóa hết và làm lại từ đầu.
Tuần 1: Cài đặt mà cũng fail
Bạn có thể nghĩ: “Cài đặt thì fail cái gì?” — Tôi cũng nghĩ vậy. Nhưng tôi đã dùng Node.js 14 trong khi Playwright yêu cầu Node 16+. Error message không hề nói rõ điều đó. Tôi ngồi Google hơn nửa ngày mới tìm ra.
npm init playwright@latest
Error: Cannot find module '../build/Release/native_messaging_host'
nvm install 18
nvm use 18
💡 Bài học
Trước khi làm gì, kiểm tra phiên bản Node.js. Câu lệnh node --version mất 2 giây. Debug error mờ mắt mất nửa ngày.
Hành trình thật — tuần qua tuần
Tuần 1
Cài đặt thành công, viết test đầu tiên
Tìm hiểu cấu trúc thư mục, page object cơ bản. Hứng khởi.
Tuần 2
Bị ám bởi auto-waiting — cứ nghĩ phải thêm sleep()
Tư duy Selenium cũ khiến tôi thêm sleep() khắp nơi. Test chậm kinh khủng.
Tuần 3
Selector hell — locator nào đúng, nào sai?
getByRole vs getByTestId vs CSS selector. Tôi dùng tất cả lẫn lộn. Ai review code cũng lắc đầu.
Tuần 4
Hiểu ra triết lý của Playwright
Đọc lại docs từ đầu. Mọi thứ bắt đầu “click”.
Tuần 5–6
Viết lại toàn bộ test suite — sạch và stable
Pass CI/CD liên tục. Dev ngừng than phiền. Team hạnh phúc.
Sai lầm lớn nhất: mang tư duy Selenium vào Playwright
Đây là điều tôi muốn gào vào tai bất kỳ tester nào đang chuyển từ Selenium sang Playwright: hãy quên những gì bạn biết về wait.
Với Selenium, tôi quen thêm explicit wait hoặc sleep() để đợi element. Với Playwright, điều đó gần như không cần thiết vì Playwright có auto-waiting — nó tự chờ element ở trạng thái sẵn sàng trước khi tương tác.
await page.waitForTimeout(3000);
await page.click('#submit-btn');
await page.getByRole('button', { name: 'Đăng nhập' }).click();
❌ Sai lầm #2
Test suite của tôi tuần 2 chạy mất 18 phút vì đầy waitForTimeout(). Sau khi xóa hết và tin tưởng vào auto-waiting, còn 6 phút. Cùng test coverage, cùng kết quả, nhanh gấp 3 lần.
Selector: tôi đã dùng sai loại trong 2 tuần
Playwright có nhiều cách để chọn element, nhưng chúng không bình đẳng. Tôi ban đầu dùng CSS selector vì quen — đó là lựa chọn kém bền nhất.
page.getByRole('button', { name: 'Xác nhận' })
page.getByLabel('Email')
page.getByPlaceholder('Nhập mật khẩu')
page.getByTestId('login-btn')
page.getByText('Đăng nhập')
page.locator('.btn-primary > span:nth-child(2)')
💡 Bài học
Nếu test bạn hay fail khi dev thay đổi CSS hay HTML nhỏ — selector đang là vấn đề. Hãy ưu tiên getByRole và getByTestId. Nói chuyện với dev để họ thêm data-testid vào các element quan trọng.
Khoảnh khắc “à ra thế” — khi mọi thứ click vào nhau
Tuần 4, tôi ngồi đọc lại toàn bộ trang Best Practices của Playwright docs. Lần này không đọc để tìm cách fix bug — đọc để hiểu triết lý thiết kế. Và tôi nhận ra: Playwright được thiết kế để test từ góc nhìn của user, không phải từ góc nhìn của HTML.
Đó là bước ngoặt. Từ lúc đó, mỗi khi viết test, tôi tự hỏi: “User thực sự làm gì ở đây?” thay vì “Element nào mình cần click?”
“Playwright được thiết kế để test từ góc nhìn của user — không phải từ góc nhìn của HTML. Câu hỏi không phải ‘element nào tôi click?’ mà là ‘user thực sự làm gì?'”
Kết quả sau 6 tuần
Bộ test mới với Playwright: 312 test cases, chạy song song trên 3 browser (Chrome, Firefox, Safari), thời gian CI xuống còn 8 phút từ 34 phút trước đó. Flaky test: từ 23% còn 1.2%.
✅ Kết quả thực tế
Lần đầu tiên trong lịch sử team, chúng tôi deploy thứ Sáu mà không ai run sợ. Dev không còn mở Slack lúc 6 giờ tối để hỏi “test có pass không?” Đó là cảm giác xứng đáng nhất sau 6 tuần vật lộn.
3 điều tôi khuyên nếu bạn bắt đầu hôm nay
Thứ nhất: đọc docs trước khi code. Tôi biết, tôi biết — nghe nhàm. Nhưng Playwright docs thực sự rất tốt và có nhiều ví dụ thực tế. Đặc biệt đọc phần Best Practices và Auto-waiting trước.
Thứ hai: dùng Playwright Inspector ngay từ đầu. Lệnh npx playwright test --debug mở ra một công cụ cực kỳ hữu ích để bạn thấy test đang chạy như thế nào, element nào được chọn, bước nào fail.
Thứ ba: đừng học một mình. Tôi đã mất 2 tuần lẩn quẩn vì ngại hỏi. Khi bắt đầu post câu hỏi lên Discord của Playwright và các nhóm tester Việt Nam, mọi thứ nhanh hơn nhiều. Cộng đồng rất nhiệt tình.
Sưu tầm
Bạn đang học Playwright và gặp khó khăn nào đó?
Comment bên dưới — tôi đọc và trả lời từng bình luận.