Nỗi khổ chạy test tuần tự và lối thoát mang tên Selenium Grid
Hồi mới làm Automation, mình thường chạy script trực tiếp trên máy cá nhân. Mọi việc vẫn ổn cho đến khi bộ test case chạm mốc 300. Mỗi lần chạy Regression Test mất hơn 2 tiếng đồng hồ. Ngồi chờ đợi kết quả thực sự là một cực hình. Chưa kể, việc cài đặt đủ loại driver cho Chrome, Firefox hay Edge khiến máy tính trở thành một “bãi rác” cấu hình.
Selenium Grid xuất hiện như một cứu cánh. Nó cho phép bạn phân tán các kịch bản kiểm thử lên nhiều máy (Node) để chạy cùng lúc. Tuy nhiên, cài đặt kiểu truyền thống bằng file .jar và cấu hình Java thủ công rất mất thời gian. Mỗi lần cần thêm Node hay cập nhật phiên bản trình duyệt, mình lại phải loay hoay setup từ đầu.
Sau 6 tháng vận hành thực tế, mình nhận ra kết hợp Docker Compose với Selenium Grid là hướng đi tối ưu nhất. Bạn có thể dựng cả hệ thống chạy test đa trình duyệt chỉ với một câu lệnh. Dưới đây là quy trình mình đã áp dụng để tối ưu hiệu suất cho team.
Chuẩn bị môi trường
Để bắt đầu, máy bạn cần có sẵn hai công cụ cơ bản:
- Docker Desktop (Windows/Mac) hoặc Docker Engine (Linux).
- Docker Compose (thường tích hợp sẵn trong bộ cài Docker).
Hãy mở terminal và kiểm tra nhanh bằng lệnh:
docker --version
docker-compose --version
Xây dựng file docker-compose.yml tối ưu
Thay vì quản lý từng container rời rạc, mình sẽ dùng Docker Compose để gom tất cả về một mối. Bạn tạo một thư mục dự án, sau đó tạo file docker-compose.yml với nội dung sau:
version: "3.8"
services:
selenium-hub:
image: selenium/hub:4.15.0
container_name: selenium-hub
ports:
- "4444:4444"
environment:
- GRID_MAX_SESSION=16
- GRID_BROWSER_TIMEOUT=300
chrome:
image: selenium/node-chrome:4.15.0
shm_size: 2gb
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=4
firefox:
image: selenium/node-firefox:4.15.0
shm_size: 2gb
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=4
Những lưu ý kỹ thuật không thể bỏ qua
- shm_size: 2gb: Đây là chi tiết sống còn. Mặc định Docker chỉ cấp 64MB cho bộ nhớ đệm
/dev/shm, khiến Chrome rất dễ crash khi tải trang nặng. Hãy tăng lên ít nhất 2GB để trình duyệt chạy mượt mà. - SE_NODE_MAX_SESSIONS: Thông số này quyết định số lượng trình duyệt chạy đồng thời trên một Node. Mình thường để là 4 để cân bằng giữa hiệu năng và tài nguyên RAM.
- selenium-hub: Đóng vai trò bộ não điều phối, tiếp nhận script và phân bổ tới các Node đang rảnh.
Trong quá trình cấu hình, nếu cần kiểm tra lại file YAML hoặc log JSON từ Hub, bạn có thể dùng JSON Formatter tại Toolcraft. Công cụ này giúp định dạng lại dữ liệu thô cực nhanh, tiết kiệm thời gian hơn nhiều so với việc soi code bằng mắt thường.
Khởi động và kiểm tra thành quả
Tại thư mục chứa file, bạn thực thi lệnh:
docker-compose up -d
Sau khi Docker kéo xong image, hãy truy cập http://localhost:4444. Giao diện Selenium Grid Console sẽ hiện ra, hiển thị danh sách các Node Chrome và Firefox đã sẵn sàng thực chiến.
Điểm mạnh nhất của Docker là khả năng mở rộng (Scaling). Nếu cần chạy 10 luồng Chrome thay vì 4, bạn chỉ cần gõ:
docker-compose up -d --scale chrome=3
Chỉ mất chưa đầy 10 giây, hệ thống sẽ tự nhân bản thêm các container mới mà không cần sửa bất kỳ dòng code cấu hình nào.
Kết nối script test vào Grid
Thay vì khởi tạo driver cục bộ, bạn trỏ script về phía Hub. Ví dụ với Python:
from selenium import webdriver
options = webdriver.ChromeOptions()
# Kết nối tới Hub đang chạy tại cổng 4444
driver = webdriver.Remote(
command_executor='http://localhost:4444/wd/hub',
options=options
)
try:
driver.get("https://itfromzero.com")
print(f"Tiêu đề trang: {driver.title}")
finally:
driver.quit()
Bài học thực tế sau 6 tháng vận hành
Khi áp dụng cụm Grid này cho các đợt Regression Test hàng đêm, mình rút ra 3 kinh nghiệm xương máu:
- Kiểm soát RAM: Trình duyệt ngốn tài nguyên cực lớn. Một Node chạy 4 session Chrome cần khoảng 2GB – 3GB RAM thực tế để không bị treo giữa chừng.
- Dọn dẹp session “zombie”: Luôn đặt
GRID_BROWSER_TIMEOUT. Nếu script bị crash mà không kịp gọidriver.quit(), Hub sẽ tự động giải phóng trình duyệt sau một khoảng thời gian nhất định. - Tốc độ thực tế: Sau khi chuyển sang chạy song song 8 luồng trên Grid, bộ test 300 cases của team mình giảm từ 120 phút xuống còn vỏn vẹn 18 phút.
Sử dụng Docker Compose cho Selenium Grid không chỉ giúp tăng tốc độ kiểm thử mà còn đảm bảo môi trường đồng nhất từ máy dev đến server CI/CD. Chúc các bạn sớm tối ưu được hệ thống automation của mình!
