<Selenium 2 Testing Tools> Chương 4: Design Patterns
Bài đăng này đã không được cập nhật trong 3 năm
Ở chương này, chúng ta sẽ cùng tìm hiểu về các mẫu thiết kế tốt cho việc tạo các đoạn code có thể sửa chữa và tái sử dụng cho Selenium test. Điều này có nghĩa nếu có thay đổi nào đó trong ứng dụng web hay thay đổi cách tìm kiếm phần tử chẳng hạn, ta có thể chỉ cần thay đổi 1 lần và sửa chữa mọi thứ rất nhanh chóng. Ở chương này, ta sẽ học về:
- Thiết kế Page Object
- Sử dụng Page Factory trong Page Objects
- Sử dụng LoadableComponents Ta cùng bắt đầu thôi...
Điểm khởi đầu quan trọng
Ở chương này, giả sử tất cả các file đều có trạng thái import như bên dưới:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
Page Objects
Ở phần này, ta sẽ tìm hiểu về cách áp dụng thực hành tốt nhất cho kiểm thử. Bạn sẽ học cách để bảo trì test suite cho phép cập nhập test trong vài giây. Ta sẽ tìm hiểu về việc tạo DSL để mọi người có thể nhìn thấy ý định của mình. Ta cũng sẽ tạo test sử dụng Page Object Pattern.
Thời điểm hành động – cài đặt test
Hãy tưởng tượng bạn có 1 bài kiểm tra như sau: đang trên 1 trang web, yêu cầu bạn đang nhập rồi di chuyển đến 1 trang nhất định. Hoặc tưởng tượng bạn cần 1 kiểm thử yêu cầu bạn ở 1 trang nhất định.
Ở cả hai tình huống đó, cách nhanh nhất để tìm ra trang hiện tại bạn đang truy cập và di chuyển đến một trang nào đấy là bắt đầu kiểm thử. Hãy xem ví dụ dưới đây nhé: Tạo 1 lớp Java mới trong IDEA:
- Import các package Selenium thích hợp
- Tạo phương thức setup() và teardown() . Tôi thích kiểm thử kiểu JUnit 4 và sẽ chỉ ra ví dụ code có kèm theo chú thích
- Ta cần kiểm tra trang hiện tại có phải là trang đúng không. Để làm điều này, ta sẽ sử dụng selenium.getTitle để xem title của trang và sau đó nếu không đúng thì di chuyển đến link chapter2. Làm vậy là bởi việc di chuyển đến trang chậm hơn kiểm tra title của trang hay bất kì một call nào khác đến trang vừa được tải.
- Sau đó ta cần xác nhận nó có đúng và làm việc có phù hợp không. Dưới đây là 1 mẩu code về cách chúng ta làm với điều này:
if (!"Page 2".equals(selenium.getTitle())){
selenium.get(
"http://book.theautomatedtester.co.uk/chapter2");
}
- Hãy tạo kiểm thử để kiểm tra các item trên trang nhé
Điều gì vừa xảy ra?
Ta vừa thấy cách kiểm tra một cái có phải là mong muốn của kiểm thử hay không. Nếu đúng, kiểm thử sẽ tiến hành như ta mong muốn. Nếu không phải là cái ta mong muốn thì sẽ di chuyển kiểm thử đến trang đúng và tiến hành với trang đó. Nếu truy cập vào @Before, bạn sẽ không phải bắt đầu kiểm thử của bạn. Bây giờ hãy xem cách ta làm cho kiểm thử của mình thêm tính có thể sửa chữa bằng cách phân vùng và cho vào trong phương thức khác.
Thời điểm để hành động – chuyển các bước Selenium vào phương thức riêng để có thể sửa chữa kiểm thử
Hãy tưởng tượng rằng bạn chỉ cần kiểm thử 1 trang trên site và bạn có 1 vài test cho trang này. Có rất nhiều test sẽ sử dụng code giống nhau lặp đi lặp lại. Điều này sẽ gây phiền hà cho việc sửa chữa nếu có một cái thay đổi trên trang nghĩa là ta phải đi qua tất cả các test để sửa 1 issue này. Cách để sửa là cấu trúc lại test để chúng đơn giản hơn và vì thế mà dễ đọc hơn.
- Hãy cùng tạo nhiều test như bên dưới:
@Test
public void shouldCheckButtonOnChapter2Page(){
selenium.get("http://book.theautomatedtester.co.uk");
selenium.findElement(By.link, "Chapter2").click();
Assert.assertEqual(selenium.findElements(
By.id"but1").getSize(), 1);
}
@Test
public void shouldCheckAnotherButtonOnChapter2Page(){
selenium.get("http://book.theautomatedtester.co.uk");
selenium.findElement(By.link, "Chapter2").click();
Assert.assertEqual(selenium.findElements(
By.id,"verifybutton").getSize(), 1);
}
-
Sử dụng ví dụ trên, giờ thì chia nhỏ chúng ra
-
Ở tất cả các ví dụ ta đều có thể thấy đều có bước mở 1 site Hãy di chuyển chúng vào 1 phương thức riêng. Để làm được điều này trong IDEA, bạn đánh dấu sáng các dòng bạn muốn cấu trúc lại sau đó right-click. Sử dụng danh sách context và sau đó là phương thức extract.
-
Sau đó bạn sẽ thấy 1 dialog yêu cầu bạn đặt tên cho phương thức. Hãy đặt 1 cái tên có ý nghĩa. Ở đây tôi gọi nó là loadHomePage như bạn có thể nhìn thấy ở hình chụp bên dưới:
-
Bây giờ làm tương tự với các phần khác của test để làm cho tét trông ngắn gọn hơn.
-
Lớp test của bạn trông sẽ giống như thế này:
@Test
public void shouldCheckButtonOnChapter2Page(){
loadHomePage();
clickAndLoadChapter2();
Assert.assertEquals(selenium.findElements(
By.id("but1")).size(), 1);
@Test
public void shouldCheckAnotherButtonOnChapter2Page(){
loadHomePage();
clickAndLoadChapter2();
Assert.assertEquals(selenium.findElements(
By.id("verifybutton")).size(), 1);
private void loadHomePage() {
selenium.get("http://book.theautomatedtester.co.uk");
}
private void clickAndLoadChapter2() {
selenium.findElement(By.linkText("Chapter2")).click();
}
Điều gì vừa xảy ra?
Ta chỉ mới bắt đầu làm cho kiểm thử thêm tính có thể duy trì được, đã thấy cách chia nhỏ thành các bài kiểm thử ngắn gọn và dễ đọc hơn. Điều này cũng làm cho kiểm thử dễ kiểm soát hơn nhiều vì giả sử nếu bạn thay đổi liên kết gốc từ "Chapter2" đến "Chapter 2", bạn sẽ chỉ cần sửa nó ở 1 nơi hơn là n nơi , n là số lần lặp lại trong lớp thử nghiệm. Bây giờ ta hãy tìm hiểu cách sử dụng Page Object Pattern cho việc tạo DSL trên trang web nhé.
Thời điểm để hành động – sử dụng Page Object Pattern để thiết kế test
Giả sử rằng bạn có 1 site có rất nhiều trang khác nhau mà bạn cần kiểm thử. Điều này khá phổ biến với nhiều site. Ta có thể tạo 1 đối tượng mô tả trang và sau đó đưa đối tượng Selenium này vào ngôn ngữ chương trình. Giờ mình cùng tạo Page Object đầu tiên với trang home nhé.
-
Tạo 1 lớp Java mới trong IDEA gọi là HomePage.
-
Import packages thích hợp để test có thể chạy được.
-
Giờ ta sẽ cần 1 kỹ sư để xử lý Selenium. Có thể bạn muốn chuyển đến trang home khi nó được tạo. Một ví dụ cho điều này bạn có thể xem ở bên dưới:
HomePage.java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class HomePage{
WebDriver selenium;
public HomePage(WebDriver selenium){
this.selenium = selenium;
}
public Chapter2 clickChapter2(){
clickChapter("2");
return new Chapter2(selenium);
}
private void clickChapter(String number){
selenium.findElement(By.linkText("Chapter"+number)).click();
}
}
Chapter2.java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class Chapter2 {
WebDriver selenium;
public Chapter2(WebDriver selenium){
this.selenium = selenium;
if (!"Chapter 2".equalsIgnoreCase(
this.selenium.getTitle())){
selenium.get(
"http://book.theautomatedtester.co.uk/chapter2");
}
}
public boolean isButtonPresent(String button){
return selenium.findElements(By.xpath("//input[@id='" +
button + "']")).size()>0;
}
}
BestPractises3.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class BestPractises3 {
WebDriver selenium;
@Before
public void setUp(){
selenium = new FirefoxDriver();
}
@After
public void tearDown(){
selenium.quit();
}
@Test
public void
ShouldLoadTheHomePageAndThenCheckButtonOnChapter2(){
selenium.get("http://book.theautomatedtester.co.uk");
HomePage hp = new HomePage(selenium);
Chapter2 ch2 = hp.clickChapter2();
assertTrue(ch2.isButtonPresent("but1"));
}
}
- Nếu bạn tạo 3 file này, bạn sẽ thấy nó pass. Test giờ đã ngắn gọn và dễ hiểu hơn nhiều để sửa chữa.
Điều gì vừa xảy ra?
Ở phần này, ta có thấy việc tạo test sử dụng mẫu thiết kế Page Object. Cái này cho phép ta tạo đối tượng trong 1 ngôn ngữ lập trình và sau đó đưa đối tượng Selenium sang nó để dẫn dắt trình duyệt. Điều này tạo ra 1** DSL** thực sự tốt cho phép tất cả các nhóm trong vòng đời phát triển hiểu. Ta tạo 1 đối tượng Java cho từng trang ta muốn làm việc. Sau đó chỉ là tạo đối tượng lớp để làm việc với trang đó. Khi bạn di chuyển giữa các trang, bạn phải click vào link và phương thức kiểm soát di chuyển trang sẽ trả về 1 đối tượng miêu tả 1 trang mới. Các đối tượng sẽ không nắm giữ việc xác nhận, nó luôn luôn được làm trong khi kiểm thử.
Pop quiz – Page Object design
- Mẫu thiết kế Page Object là cái gì?
Nguồn dịch:
Sách Selenium 2 Testing Tools- Beginner's Guide [eBook] - David Burns
All rights reserved