[Bài 12] Refactor code dựa vào việc sử dụng POM (Page Object Model)

Mình nhắc lại kiến thức lập trình một chút.

  • OOP (Object-Oriented Programming) nhìn tất cả mọi vật là Object – đối tượng. Đối tượng được định nghĩa trong các class có các thuộc tính và các hành động khác nhau.
  • POM (Page Object Model) là 1 design pattern giúp mô hình hóa các pages, hoặc các phần (component: header, footer, menu…) trong page của trang web thành mỗi đối tượng riêng biệt. Mỗi component / page sẽ gói gọn tất cả các hành động và các thuộc tính của component / page đó.

Để phù hợp với Project, mình cũng cần tách biệt giữa các Page và Test. Ta không thể viết chung tất cả vào 1 class như chúng ta đã viết ở các bài trước. Ta cần tổ chức lại project 1 chút.

Những việc cần phải làm là:

  • Tách class LoginTest ra thành 2 class: LoginPage và LoginTest
  • Tách class AddNewPostTest ra thành 2 class: AddNewPostPage và AddNewPostTest
  • Tạo 1 class BasePage

I. Tách class LoginTest ra thành 2 class: LoginPage và LoginTest

LoginPage: Nơi chứa các những gì thuộc về LoginPage ví như: các element, function login.

LoginPage mới như sau:

public class LoginPage {

	public String user_login = "user_login";
	public String user_pass = "user_pass";
	public String submitBtn = "wp-submit";

	WebDriver driver;

	public LoginPage(WebDriver driver) {
		this.driver = driver;
	}

	public void login(String userName, String password) {
		driver.findElement(By.id(user_login)).sendKeys(userName);
		driver.findElement(By.id(user_pass)).sendKeys(password);
		driver.findElement(By.id(submitBtn)).click();
	}

}

Cái class này hàm khởi tạo Object (constructor) có 1 tham số chính là driver. Nếu không có tham số này sẽ báo lỗi.

public LoginPage(WebDriver driver) {
	this.driver = driver;
}

Từ đó, class LoginTest cũng thay đổi theo:

public class LoginTest extends BaseTest{
	LoginPage loginPg;
       
    @Test
	public void loginWithBlankField() {
		loginPg = new LoginPage(driver);
		loginPg.login("", "");
		Assert.assertEquals(driver.getCurrentUrl(), BaseTest.URL_login);
	}

	@Test
	public void loginByAdmin() {
		loginPg = new LoginPage(driver);
		loginPg.login("giang", "123456789");
		Assert.assertEquals(driver.getCurrentUrl(), BaseTest.URL_dashBoard);
	}

}

Từ class LoginTest, muốn sử dụng function ở class LoginPage, ta cần phải khởi tạo 1 Object của class đó.

loginPg = new LoginPage(driver);

Sau đó từ Object loginPg ta sẽ access đến function login().


II. Tách class AddNewPostTest ra thành 2 class: AddNewPostPage và AddNewPostTest.

Mình sử dụng các kỹ thuật refactor mà mình đã giới thiệu qua các bài trước để viết thành như thế này.

public class AddNewPostPage {

	
	public String URL_addNew = "http://localhost/wp/wp-admin/post-new.php";
	public String iframe = "content_ifr";
	public String titleID = "title";
	public String bodyID = "tinymce";
	public String title = "This is the title";
	public String body = "This is the body";
	public String PublishBtn = "publish";

	WebDriver driver;

	public AddNewPostPage(WebDriver driver) {
		this.driver = driver;
	}

	public void addANewPost(String title, String body) {
		driver.findElement(By.id(titleID)).sendKeys(title);
		driver.switchTo().frame(iframe);
		driver.findElement(By.id(bodyID)).sendKeys(body);
		driver.switchTo().defaultContent();
		driver.findElement(By.id(PublishBtn)).click();
	}

	public void goToDetailPage() {
		driver.findElement(By.cssSelector("#message a")).click();
	}

}

Class AddNewPostTest như sau:

public class AddNewPostTest extends BaseTest {

	LoginPage loginPg;
	AddNewPostPage addNewPg;

	@Test
	public void addNewPost() {
		loginPg = new LoginPage(driver);
		addNewPg = new AddNewPostPage(driver);

		loginPg.login("giang", "123456789");
		driver.get(addNewPg.URL_addNew);
		addNewPg.addANewPost(addNewPg.title, addNewPg.body);
		addNewPg.goToDetailPage();

		String titlePost = driver.findElement(By.tagName("h1")).getText();
		Assert.assertEquals(titlePost, addNewPg.title);
	}

}

III. Tạo 1 class BasePage

Mình thấy LoginPage và AddNewPostPage không có điểm gì chung, thôi mình tạm thời bỏ qua, lúc nào cần quay lại sau.

Vậy là 2 trong số 4 vấn đề của bài 11 đã được mình giải quyết. Còn 2 vấn đề nữa sẽ được xử lý ở bài tiếp theo nhé. Bài này vì code dài nên mình ít giải thích, bạn nào có gì chưa hiểu cứ để lại comment bên dưới. Thanks

0 0 votes
Article Rating
Subscribe
Notify of
guest
12 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
trackback

[…] ← Previous Next → […]

trackback

[…] thế mà ta cứ “đẻ sòn sòn” Class mà phải bám sát vào việc sử dụng POM cũng như là nhiệm vụ của mỗi […]

Lv
Lv
4 years ago

cho mình hỏi tại sao phần driver.get(addNewPg.URL_addNew); này không thực hiện trong addANewPost của AddNewPostPage mà phải nằm trong AddNewPostTest vậy bạn ?

Lv
Lv
4 years ago
Reply to  Giang Nguyen

oh..thank bạn 😀

Hoàng Thị Hiên
Hoàng Thị Hiên
4 years ago

Khi em chia ra theo dạng Page Object Model em chạy file Test thì n k chạy theo TestNG, mà nó lại hiện ra junit Test và chạy k được. Phần này em chưa hiểu rõ.Anh giải thích giúp em với ạ. Em cảm ơn ạ!

trackback

[…] trong bài về Page Object mình đã có nói là ta mô hình hóa mỗi page hoặc mỗi phần của 1 page thành 1 […]

Trần Thế Anh
Trần Thế Anh
2 years ago

https://imgur.com/DXfhRye
E thấy đoạn code này mỗi test case lại phải khởi tạo lại Object
loginPg = new LoginPage(driver);
Có cách nào để chỉ cần gọi một lần duy nhất không ạ

Ẩn danh
Ẩn danh
11 months ago

Phần verify thì nên để vào đâu ạ