SF

""

Page Object Model framework trong automation testing

 

Page Object Model framework trong automation testing



Thời gian gần đây, Page object model (POM) framework đã dần trở nên phổ biến trong giới automation framework, và đang được sử dụng trong rất nhiều các dự án của các công ty bởi tính dễ dàng trong việc bảo trì và giảm thiểu việc trùng lặp của code.

Một ưu điểm lớn mà Page Object Model mang lại đó là bạn sẽ không phải thay đổi các test script đã xây dựng nếu như có sự thay đổi về UI của các page, việc cần làm là chỉ cần chỉnh sửa trong một class đã được phân tách theo cấu trúc, mà không phải nhảy đi khắp nơi trong project để tìm rồi sửa từng chỗ một, mà việc ấy thì tiềm ẩn nguy cơ nhầm lẫn, thiếu sót rất là cao.

Mình có thể đưa ra một ví dụ đơn giản về một form thêm mới hàng hóa chẳng hạn, như thiết kế ban đầu thì chỉ có 10 trường thôi, nhưng mà sau đó lại có yêu cầu bổ sung thêm vài trường nữa, mà thứ tự của các trường này lại nằm xen kẽ trong các trường mà mình đã xây dựng trước đây, và việc thêm trường này lại ảnh hưởng đến cấu trúc HTML của trang, những phần tử nào mình phải sử dụng xPath, thì đúng là việc cập nhật các thay đổi này không hề nhanh chút nào. Bên cạnh đó các phần tử ban đầu được dùng lại còn xuất hiện ở một vài nơi  và cho một vài chức năng khác nữa.

Nhưng mà, vì lúc trước mình đã áp dụng mô hình Page Object Model nên là bây giờ mình chỉ cần tìm đến class có chứa thông tin của đối tượng này – ví dụ class AddItemPage, rồi bổ sung hay cập nhật thêm các thuộc tính vào đó và mình cũng không cần phải đi đến nhiều các class khác nhau để cập nhật thêm những thông tin kia. Đơn giản đúng không!

page object locators

Như hình ảnh phía trên là đoạn code có các locator của các phần tử được nhóm ở ngay trên đầu của class. Với cách này thì test script của chúng ta trông sẽ gọn gàng và dễ đọc hơn, từ đó có thể dễ dàng tìm ra được dòng thông tin của một phần tử bất kì nào có mặt trong đó, nên việc cập nhật hay thay đổi thông tin bạn chỉ cần thay đổi ở đây thôi mà không cần phải đi tìm xem nó có còn ở đâu nữa cần chỉnh sửa hay không.

Page object model là việc thực hiện tách các chức năng hoặc các component có thể sử dụng lại được hoặc được dùng và gọi đến nhiều lần vào trong một class base nào đó. Ví dụ như việc ta tách riêng các nhóm chức năng sau thành các class page tương ứng như: Home page, login page, Create Account, hay Forgot password page …

Với các class page như trên ta có thể tạo ra các class như: HomePage.class, LoginPage.class, CreateAccountPage.class, ForgotPasswordPage.class. Mỗi class ta sẽ xác định và viết các hàm xử lý riêng cho từng đối tượng trong trang tương ứng.

page object classes

Mình có thể lấy ví dụ như ở trang chủ của Google, ta có thể dễ dàng quan sát được ở đây có các chức năng lớn như Tìm kiếm, Đăng ký, +You, Hình ảnh, các Link về chính sách sử dụng dịch vụ của Google…, Tùy theo nhóm chức năng và theo nhu cầu của người sử dụng, thì sẽ có các class chức năng tương ứng. Từ đó, ta sẽ tách các class theo các function này, sau đấy là xác định và gom nhóm các method có thể sử dụng lai được hoặc dùng chung được.

Các lợi ích mà Page Object Model mang lại:

  1. Giúp project của bạn có một bố cục rõ ràng hơn, tách biệt giữa kịch bản test và việc xử lý các thuộc tính của các phần tử trên từng trang ứng dụng.
  2. Ta sẽ có một kho lưu trữ độc lập với các kịch bản test, nó cung cấp các service dùng chung, hoặc tái sử dụng được từ một base nào đó, chứ không nằm rải rác ở nhiều nơi trong project.

Cùng xem ví dụ thực tế dưới đây để có cái nhìn trực quan hơn nha.

Ví dụ, ta có một đoạn code đơn giản dùng cho chức năng đăng nhập như sau:

/***   
* Tests login functionality   
*/ 
public void loginTestCase() {        
   driver.navigate().to(URL);        
   driver.findElement(By.name("signIn")).click();        
   driver.findElement(By.id("username")).sendKeys("testuser");        
   driver.findElement(By.id("password")).sendKeys("testpassword");        
   driver.findElement(By.name("loginbtn")).click();  
               
   WebDriverWait wait = new WebDriverWait(driver, 10);        
   wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("profile")));        
   String Expected=driver.findElement(By.id("message")).getText();        
   Assert.assertEquals(Expected, "Welcome"); 
}


Đoạn code trên thì các test và locator của element đang được gộp chung trong dòng xử lý của từng đối tượng. Nếu như có sự thay đổi và cập nhật UI cho form đăng nhập này, thì ta sẽ phải đi cập nhật cho từng phần tử ở nhiều nơi. Công việc này trở nên khó khăn hơn trong vấn đề xác định các vị trí của các phần tử được thay đổi, như xác định nó nằm ở đâu trong class, và có nằm ở class nào nữa không trong project.

Bây giờ ta sẽ thực hiện tách đoạn code trên sử dụng page object model:

/*** 
* Tests login functionality */        
public void loginTestCase() { 
  // To go to home page 
   homePage.gotoHomePage(); 
  //To click on SignIn link 
   accountLoginPage = homePage.clickOnSignIn() 
  //To verify if user is navigated to sign-in page 
   Assert.assertTrue(accountLoginPage.verifyPage()); 
  //Login to the account 
   accountLoginPage.userLogin(username,password); 
  //To verify if user is navigated to user home page after successfull login 
   Assert.assertTrue(userHomePage.verifyPage()); 
}

Trong đoạn code đã tách trên, ta không sử dụng trực tiếp các method tìm locator của đối tượng. Ta sẽ gọi đến các hàm đã được định nghĩa ở các page khác nhau khi cần. Chỉ xét trên diện thẩm mĩ, có thể thấy code của ta trông đã đỡ rối hơn rất nhiều rồi.