2012-10-31 11 views
7

我一直在爲幾個月來一直在開發Selenium WebDriver基礎架構的團隊工作,並且關於我們從測試用例和頁面對象訪問驅動程序對象的方式正在困擾着我。複製/傳遞WebDriver的實例是如何工作的,是否危險?

我們的測試用例創建一個新的WebDriver實例並打開瀏覽器。這個新實例存儲在測試用例類中。

然後,測試用例實例化一個頁面對象。跟着Selenium's Page Object Pattern一起,這些頁面對象將WebDriver作爲它的構造函數的參數(儘管我注意到在我們的版本中它不是最終的)。各種頁面對象方法使用在頁面對象的構造函數中設置的驅動程序來執行它們的操作。如果頁面對象方法導航到新的頁面對象,那麼WebDriver會傳遞給它。就像在硒的例子:

public class LoginPage { 
    private final WebDriver driver; 

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

     // Check that we're on the right page. 
     if (!"Login".equals(driver.getTitle())) { 
      // Alternatively, we could navigate to the login page, perhaps logging out first 
      throw new IllegalStateException("This is not the login page"); 
     } 
    } 

    // Conceptually, the login page offers the user the service of being able to "log into" 
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) { 
     // This is the only place in the test code that "knows" how to enter these details 
     driver.findElement(By.id("username")).sendKeys(username); 
     driver.findElement(By.id("passwd")).sendKeys(password); 
     driver.findElement(By.id("login")).submit(); 

     // Return a new page object representing the destination. Should the login page ever 
     // go somewhere else (for example, a legal disclaimer) then changing the method signature 
     // for this method will mean that all tests that rely on this behaviour won't compile. 
     return new HomePage(driver); 
    } 
} 

這使它看起來好像webdriver的實例是獨特和重要的,比如,必須從頁面對象被傳遞到頁面對象火炬。代碼的風格使我認爲我總是必須確保我使用的是上次操作中使用的驅動程序的相同實例。

但是,在頁面上存在多個頁面對象並且頁面對象方法不會返回您正在計劃使用下一頁面的頁面對象的情況下,「傳遞火炬」變得複雜或不可能。當屏幕上有兩個頁面對象時,如何在同一WebDriver實例上進行操作,並且您需要在它們之間進行切換,而無需切換到新頁面或創建新頁面對象?

所有這些混淆導致我相信沒有任何火炬傳遞實際上是必要的,甚至可能發生(所有這些頁面對象存儲對同一個WebDriver實例的引用?),但是我不知道爲什麼模式在Selenium給出的描述中被提出。

那麼,我需要擔心「傳遞火炬?」或者,即使其他頁面對象在過渡期間使用自己版本的相同WebDriver執行操作,任何頁面對象在使用其WebDriver實例化後都能正常運行?

讓WebDriver成爲一個單身人士,所有人都可以使用它,因爲我們在任何時候都不會爲每個JVM使用多個WebDriver?那麼我們就不需要在構造函數中傳遞WebDriver了。預先感謝您的任何意見。

+1

很好,在我的項目我有以下結構: BaseSeleniumTest.java這是由其他類(含設置毒鼠強與@擴展測試註釋)。所以在BaseSeleniumTest.java中,我聲明瞭WebDriver驅動程序;作爲靜態變量,並以這種方式避免創建多個webDriver實例。 –

+0

只是爲了說明這一點,在某些情況下,如果您確實需要針對給定用例使用兩個單獨的瀏覽器,則需要多個webdriver實例。 – grumpasaurus

+0

「...那麼我不知道爲什麼這個模式是在Selenium給出的描述中提出的「你能提供一個鏈接到我的回憶是他們將一個WebDriver實例傳遞給靜態方法 – grumpasaurus

回答

4

最好將webdriver標記爲整個框架的單例。我一直在使用這種模式,它工作正常。
注意:處理並行執行時應小心。

@CodeEnthusiastic 例如拿一個類GeneralLibrary,那創建一個WebDriver

GeneralLibrary擴展在頁面對象模型類的超類

+0

肯定會喜歡使用單例,特別是如果WebDriver實際上確實保持某種狀態信息,這就要求所有頁面對象和操作都使用_same_ WebDriver。 我不想_我們計劃在同一臺機器上使用相同的JVM進行並行執行。我到目前爲止使用Selenium的經驗讓我擔心這樣做太脆弱了 - 我擔心一個瀏覽器的操作會搞亂另一個瀏覽器的執行。 –

+0

@rironin,每個webdriver實例都與一個會話id相關聯,該id可以被假定爲隨機生成的32位密鑰。因此,一個瀏覽器的行爲根本不會影響其他瀏覽器 –

+0

有意義的是,一個瀏覽器根本不會直接影響另一個瀏覽器,但是IE瀏覽器窗口沒有聚焦時,特別是在運行自動化方面沒有問題?如果瀏覽器窗口被不同的瀏覽器窗口覆蓋,如果瀏覽器被最小化等,所有自動化調用的功能是否同樣好?我覺得如果不能確保正在操作的瀏覽器能夠集中注意力,或者如果您在同一臺計算機上同時運行多個測試,就不會看到它們。 –

相關問題