2014-10-27 60 views
2

我到頁面對象模式下面的鏈接和概念是好的,頁對象模式DESGIN

https://code.google.com/p/selenium/wiki/PageObjects

這裏是我的疑問:

public LoginPage typeUsername(String username) { 
    driver.findElement(usernameLocator).sendKeys(username); 
    return this;  
} 

public LoginPage typePassword(String password) { 
    driver.findElement(passwordLocator).sendKeys(password); 
    return this;  
} 


public HomePage submitLogin() {  
    driver.findElement(loginButtonLocator).submit(); 
    return new HomePage(driver);  
} 

以上硒呼叫包裹着一些功能我們在測試用例或任何頁面級函數中調用這些函數,如下所示:

public HomePage loginAs(String username, String password) { 

     typeUsername(username); 
     typePassword(password); 
     return submitLogin(); 
    } 

我的疑問是:爲什麼我們不能直接調用sendkey或在整個項目中每次提交或點擊。只有一行代碼再次用我們自己的函數包裝,這將需要更多的時間來運行代碼。

是否有任何性能問題?

回答

1

恕我直言,關鍵好處是頁面對象和測試獨立進化。如果結構發生變化,則不要更改測試,反之亦然,如果要更改測試內容,則無需更改頁面對象。將嘗試在一個示例中說明這一點

想想寫入的測試沒有遵循頁面對象模式,例如,測試產品細節。

this.driver(Find.By.id("username")).sendKeys(username); 
this.driver(Find.By.id("pass")).sendKeys(password); 
this.driver(Find.By.id("submit")).click(); 
// navigate to product listing page 
this.driver(Find.By.id("product-usb")).click(); 
// navigate to product details page 
this.driver(Find.By.id("product-a")).click(); 
assert(this and that); 

在這個例子中,如果結構發生變化(主要的重新設計),你可以強制改變你的測試。 現在,您正在預測變化,首先,您要確保沒有代碼重複,以便只在時間正確時在一個地方進行更改。拆分的方法的代碼,最合理的分割是基於邏輯單元,而斷言停留在測試他們屬於

login(username, password); 
    moveToProductListing(); 
    selectProduct(productID); 
    assert(this and that); 

的問題是,當這些方法應該可以實現,這樣就可以在測試中輕鬆訪問它們。如果它的一個實用程序類,它將很快變得臃腫。進一步思考會導致您按頁面對象進行分組。

您最終在測試中不知道正在測試的頁面的結構(它隱藏在頁面對象中)以及頁面對象不知道您正在測試的特定斷言的任何內容。

1

由於您已經開始使用Selenium文檔。如果你看看這些Test design considerations,我想它也會有幫助。至於除了@Master從答案,你會看到

結束語硒呼籲

與任何編程,你將要使用 效用函數來處理,否則將被複制整個代碼 你的測試。防止這種情況的一種方法是將經常使用的硒調用與您自己的 設計的函數或類方法進行包裝。

並通過WebElements Presence的'安全操作'進行擴展。

關於Page對象,很高興看到PageFactory的提示。

0

我認爲這個問題和你的疑惑圍繞上基本和furthor更多的我會盡量準確地回答

什麼是頁面對象設計模式?

好,頁面對象是某種API來一個網頁(或視圖),您在您的系統擁有的,讓我們把它看成是更多的「服務」頁面給出了測試儀...

一旦它被看作是這樣,我相信它更容易想到的動機......

頁面對象知道它的內部匹配的HTML頁面(或視圖)和獨自知道它...

例如,如果我們想要執行登錄(作爲用戶),我們提供這些服務:

  • 我們在用戶名輸入中輸入用戶名。
  • 我們可以在密碼輸入中輸入密碼。
  • 我們可以點擊'登錄'按鈕(預計失敗或成功)。

當然還有更多的「服務」給出,但我們可以在這裏停下來回到關鍵點......我們應該如何處理這些「服務」?這很容易:

我們需要創建一個「LoginPage」對象,它知道頁面的(私人)選擇器和HTML構造(ids,classes,xpaths等等)。測試人員公開什麼?我們剛剛討論過的服務...

測試人員可以要求登錄頁面輸入「TypeUsername(string inputUsername)」或TypePassword(string inputPassword) - 如果您是「LoginAsDefaultUser()」,也可以添加「Services」使用此頁面來測試其他的網頁...

的問題

儘管這一個良好的開端,它留下了很多改進的餘地。

最明顯的問題是,我們可能需要跨多個頁面對象進行常見操作。而用我們目前的方法,我們最終會得到重複的代碼。

解法

當創建的BasePage對象,它包裝硒核心,並且每個頁繼承從當前頁(直接或直接)我們正在創建沒有耦合,如果某處的頁面的動態環境(或視圖)已經改變,你只需要修復一個特定的對象。

摘要

  • 即使它被稱爲頁面對象設計模式,它更是一個視圖對象的設計模式,例如:如果在你的平臺上存在對每一個返回左邊的菜單頁面,您可以創建「MyPlatformBasePage」,並且每個視圖都將從它繼承(並且代碼複製再次消失,勝利!)
  • 頁面對象只公開提供的「服務」,請勿公開Selenium內部。
  • 頁面對象不是測試,不要斷言其結果。
  • 方法返回其他PageObjects,例如:調用「LoginAsDefaultUser」的LoginPage將導航到我們的應用程序主頁,因此我們必須返回我們的「HomePage」對象。
  • 使用乾淨的代碼原則,您提供的不同「服務」將用不同的方法表示,不要通過布爾變量來改變「服務」的邏輯。

動機

  • 每個人都可以寫信這些測試,甚至非技術的問題答案
  • 代碼現在是completey動態和封裝
  • 使用外觀層(或基頁),您可以潛力取代硒或改變版本沒有一個巨大的麻煩。