2013-08-26 34 views
13

Tại sao tôi nên sử dụng @FindBy so với WebDriver#findElement()?Selenium @FindBy vs driver.findElement()

@FindBy buộc tôi di chuyển tất cả các biến của mình sang cấp lớp (khi hầu hết trong số họ chỉ cần ở cấp phương thức). Điều duy nhất nó dường như để mua cho tôi là tôi có thể gọi PageFactory.initElements(), xử lý khởi tạo lười biếng cho tôi.

Tôi đang thiếu gì?

Trả lời

31

Nói đúng ra, @FindBy chỉ là một cách thay thế để tìm các yếu tố ("cách thông thường" là driver.findElement() như bạn đã nói).

Lợi thế lớn của chú thích đó không phải là chính nó. Nó được sử dụng tốt hơn để hỗ trợ PageObject pattern.

Trong một vài từ, các mẫu PageObject nói với bạn tạo ra một lớp cho mỗi trang của hệ thống bạn đang cố gắng sử dụng/thử nghiệm.

Vì vậy, thay vì phải (thông thường driver.findElement() code):

public class TestClass { 
    public void testSearch() { 
     WebDriver driver = new HtmlUnitDriver(); 
     driver.get("http://www.google.com/"); 
     Element searchBox = driver.findElement(By.name("q")); 
     searchBox.sendKeys("stringToSearch"); 
     searchBox.submit(); 
     // some assertions here 
    } 
} 

Bạn muốn định nghĩa một lớp cho trang (với @FindBy chú thích cho các yếu tố được sử dụng):

public class GooglePage { 
    @FindBy(how = How.NAME, using = "q") 
    private WebElement searchBox; 
    public void searchFor(String text) { 
     searchBox.sendKeys(text); 
     searchBox.submit(); 
    } 
} 

Và sử dụng nó như:

public class TestClass { 
    public void testSearch() { 
     WebDriver driver = new HtmlUnitDriver(); 
     driver.get("http://www.google.com/"); 
     GooglePage page = PageFactory.initElements(driver, GooglePage.class); 
     page.searchFor("stringToSearch"); 
     // some assertions here 
    } 
} 

Bây giờ, tôi biết điều này có vẻ dài dòng ở fi rst, nhưng chỉ cần cung cấp cho nó một thời điểm và xem xét có một số kiểm tra trường hợp cho trang đó. Nếu tên của số searchBox thay đổi thì sao? (Từ số name"q" đến số id, nói query?)

Mã nào sẽ có nhiều thay đổi để làm cho nó hoạt động trở lại? Cái có hoặc không có đối tượng trang (và @FindBy)? Nếu một trang thay đổi cấu trúc của nó rất nhiều, trong mã nào bảo trì sẽ dễ dàng hơn?

Có một số lợi ích khác, chẳng hạn như chú thích bổ sung như:

@FindBy(name = "q") 
@CacheLookup 
private WebElement searchBox; 

Đó @CacheLookup làm cho việc tra cứu cho nguyên tố này xảy ra chỉ một lần. Sau đó, nó sẽ được lưu trữ trong biến và truy cập nhanh hơn nhiều.

Hy vọng điều này sẽ hữu ích. Để biết thêm chi tiết, hãy đảm bảo kiểm tra PageFactoryPageObject pattern.

+0

cũng nói sir ... +1 bản thân tôi thích PageFactory hơn instantiation điển hình. đơn giản hơn nhiều. – sircapsalot

+1

+1 cho câu trả lời chi tiết như vậy .... – Akbar

+0

Mẫu PageObject có vẻ rất hữu ích!Nhưng, tôi không thể sử dụng mẫu đó chỉ với .findElement? – pyrrhicVictory

-1
import org.openqa.selenium.WebElement; 
import org.openqa.selenium.support.FindBy; 
public class CommonPageForStudent { 

    @FindBy(name="usname") 
    private WebElement Studentusername; 
    @FindBy(name="pass") 
    private WebElement Studentpassword; 
    @FindBy(xpath="//button[@type='submit']") 
    private WebElement StudentLetmein; 
    @FindBy(id="logoutLink") 
    private WebElement StudentlogoutLnk; 
    public void loginToStudent(String username , String password){ 
     Studentusername.sendKeys(username); 
     Studentpassword.sendKeys(password); 
     StudentLetmein.click(); 

     } 

    //when you call this methods from another class write this 2 line code that class 
    //CommonPageForStudent page = PageFactory.initElements(driver,  CommonPageForStudent.class); 
    // page.loginToStudent("",""); 

    public void logOut(){ 
     StudentlogoutLnk.click(); 
    } 
    //page.logOut(); method call 

}` 
+1

Bạn có thể thêm một số giải thích cho mã này không? – mlkn

0

Tôi không thích @FindBy chú thích bởi vì sau đó IntelliJ không còn phát hiện nếu biến đó đang được sử dụng, làm cho nó đau đớn để làm sạch.

Các vấn đề liên quan