Bài viết này hướng dẫn cách triển khai Page Object Model (POM) thuần (sử dụng By
locators) thay vì dùng PageFactory, cập nhật theo chuẩn Selenium mới nhất năm 2026.
Tại sao nên dùng POM ("thuần") thay vì PageFactory?
Mặc dù PageFactory ('@FindBy') rất phổ biến, nhưng trong các dự án lớn, việc tự quản lý locator bằng đối tượng
Mặc dù PageFactory ('@FindBy') rất phổ biến, nhưng trong các dự án lớn, việc tự quản lý locator bằng đối tượng
By giúp kiểm soát tốt hơn các vấn đề về StaleElementReferenceException và linh hoạt
hơn khi xử lý các phần tử động (Dynamic Elements).
1. Tạo Class LoginPage (Quản lý đối tượng trang)
Thay đổi so với code cũ:
- Dùng Encapsulation (private fields) để bảo vệ locator.
- Hàm trả về đối tượng (
return this) để hỗ trợ Chaining Method (viết code test liền mạch hơn).
package vn.haibgit.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage {
private WebDriver driver;
// 1. Khai báo Locators (Nên dùng private để đóng gói)
private By txtUsername = By.name("uid");
private By txtPassword = By.name("password");
private By btnLogin = By.name("btnLogin");
private By btnReset = By.name("btnReset");
// 2. Constructor
public LoginPage(WebDriver driver) {
this.driver = driver;
}
// 3. Các Action Methods
public LoginPage enterUsername(String username) {
// Tốt nhất nên clear text trước khi sendKeys
driver.findElement(txtUsername).clear();
driver.findElement(txtUsername).sendKeys(username);
return this; // Trả về chính nó để có thể gọi tiếp (Fluent Interface)
}
public LoginPage enterPassword(String password) {
driver.findElement(txtPassword).clear();
driver.findElement(txtPassword).sendKeys(password);
return this;
}
public void clickLogin() {
driver.findElement(btnLogin).click();
// Sau khi click login có thể trả về HomePage object nếu cần
}
// Hàm Wrapper xử lý trọn vẹn 1 flow
public void login(String username, String password) {
this.enterUsername(username);
this.enterPassword(password);
this.clickLogin();
}
}
2. Tạo Test Class (Thực thi kiểm thử)
Cập nhật quan trọng 2026:
- Không cần set path cho driver: Selenium Manager tự động lo liệu việc download chromedriver.
- Dùng Duration: Class
TimeUnitđã cũ, hãy dùngDuration.ofSeconds().
package vn.haibgit.tests;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import vn.haibgit.pages.LoginPage;
import java.time.Duration;
public class LoginTest {
private WebDriver driver;
@BeforeMethod
public void setUp() {
// Selenium 4.x+: Tự động tải driver, không cần System.setProperty(...)
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); // Syntax mới
driver.get("http://demo.guru99.com/v4/");
}
@Test
public void testValidLogin() {
// Khởi tạo Page Object
LoginPage loginPage = new LoginPage(driver);
// Thực hiện hành động login
// Cách viết Fluent: loginPage.enterUsername("user").enterPassword("pass").clickLogin();
// Hoặc dùng hàm wrapper:
loginPage.login("mngr588662", "YvUzUqa");
// Verify title (Ví dụ)
String expectedTitle = "Guru99 Bank Manager HomePage";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle, "Tiêu đề trang không khớp!");
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
Việc áp dụng POM giúp code sạch sẽ, dễ bảo trì và dễ mở rộng (Scalability) hơn rất nhiều so với việc viết code Spag
0 comments:
Post a Comment