2012-03-22 75 views
19

我想用不同的語言執行我的Selenium測試。是否有可能在運行時更改現有WebDriver的語言,還是必須重新創建瀏覽器實例?如何更改WebDriver的語言?

現在我只使用Firefox,但我想在稍後的某個時間點在不同的瀏覽器中執行測試。

在Firefox中我設置這樣的語言:

FirefoxProfile profile = new FirefoxProfile(); 
profile.setPreference("intl.accept_languages", "de"); 
WebDriver driver = new FirefoxDriver(profile); 

我還實施了WebDriverPool,其持有的webdriver實例,以便它可以測試之間共享。如果語言只能在創建時設置,我可以爲每個語言環境保存一個實例。

總而言之,我想知道我是否想念這裏的東西。爲什麼很難改變語言?不應該有像WebDriver.setAcceptLanguages(Locale)這樣的方法嗎?

簡而言之我有以下問題:

  1. 爲什麼沒有WebDriver.setAcceptLanguages(Locale)
  2. 如何更改dirrerent WebDrivers的語言?
  3. 我可以在運行時更改語言嗎?
  4. 你們是如何實現WebDriverPool的,或者你是否每次重新創建它們?
+2

我能想到的幾種情況:檢查日期和數字格式,並輸入不同的區域,採取不同語言的屏幕截圖,或許表現出一定的暗示,如果有人使用不支持的語言等等。我認爲,如果你的web應用程序支持多種語言對多個測試用例進行測試,對吧? – 2012-03-22 14:14:19

回答

13

我最終創建了一個WebDriverPool,爲WebDriver類型(例如FirefoxDriver.class)和Locale(例如en_US)的每個組合創建一個實例。也許這對某人有用。

public class WebDriverPool { 

    private Map<String, WebDriver> drivers = new HashMap<String, WebDriver>(); 
    private List<WebDriver> driversInUse = new ArrayList<WebDriver>(); 

    public WebDriverPool() { 
    Runtime.getRuntime().addShutdownHook(new Thread(){ 
     @Override 
     public void run(){ 
     for (WebDriver driver : drivers.values()) 
      driver.close(); 

     if (!driversInUse.isEmpty()) 
      throw new IllegalStateException("There are still drivers in use, did someone forget to return it? (size: " + driversInUse.size() + ")"); 
     } 
    }); 
    } 

    private WebDriver createFirefoxDriver(Locale locale){ 
    FirefoxProfile profile = new FirefoxProfile(); 
    profile.setPreference("intl.accept_languages", formatLocale(locale)); 
    return new FirefoxDriver(profile); 
    } 

    private String formatLocale(Locale locale) { 
    return locale.getCountry().length() == 0 
     ? locale.getLanguage() 
     : locale.getLanguage() + "-" + locale.getCountry().toLowerCase(); 
    } 

    /** 
    * @param clazz 
    * @param locale 
    * @return web driver which can be new or recycled 
    */ 
    public synchronized WebDriver getWebDriver(Class<? extends WebDriver> clazz, Locale locale){ 

    String key = clazz.getName() + "-" + locale; 

    if(!drivers.containsKey(key)){ 

     if(clazz == FirefoxDriver.class){ 
     drivers.put(key, createFirefoxDriver(locale)); 
     } 

     // TODO create other drivers here ... 

     // else if(clazz == ChromeDriver.class){ 
     //  drivers.put(key, createChromeDriver(locale)); 
     // } 

     else{ 
     throw new IllegalArgumentException(clazz.getName() + " not supported yet!"); 
     } 
    } 

    WebDriver driver = drivers.get(key); 

    if(driversInUse.contains(driver)) 
     throw new IllegalStateException("This driver is already in use. Did someone forgot to return it?"); 

    driversInUse.add(driver); 
    return driver; 
    } 

    public synchronized void returnWebDriver(WebDriver driver){ 
    driversInUse.remove(driver); 
    } 
} 
+0

我喜歡那個班,但我不明白你爲什麼評估哪個WebDriver正在使用......請問你有什麼解釋嗎? – 2012-05-23 06:41:14

+0

@Frank:你的問題是,爲什麼Class <> clazz是「getWebDriver」方法的參數?這是因爲調用測試類可以決定應該創建哪種驅動程序。我們需要這個,因爲只有InternetExplorer的測試,所以使用這個ActiveX。 – 2012-05-23 09:26:33

+0

不,我不明白你爲什麼登錄,如果一個驅動程序正在使用(私人列表 driversInUse)...只是爲了正確關閉他們? – 2012-05-23 09:42:30

-1

恐怕webdriver的整體想法是來充當瀏覽器 - 這樣你就可以改變瀏覽器的語言,但是你必須改變語言環境中的操作系統,或希望應用程序會爲你做。

例如 - 德文數字格式用逗號和英文逐點分隔十進制數。如果你想測試,數字格式的英語語言環境,並在德語語言環境中的行爲,你只能通過這兩種方法做到這一點:

  1. 德國更改操作系統區域設置爲英語或反之亦然
  2. 更改瀏覽器語言並希望應用程序會改變行爲。

回答您的問題:

  1. 沒有對webdriver的無setLocale的,因爲webdriver的模擬瀏覽器,而不是OS
  2. 我會做這樣的(Java代碼):

    private WebDriver driver; 
    
    public enum Language {en-us, de} 
    
    public WebDriver getDriver(Language lang){ 
        String locale = lang.toString(); 
        FirefoxProfile profile = new FirefoxProfile(); 
        profile.setPreference("intl.accept_languages", locale); 
        driver = new FirefoxDriver(profile); 
        return driver;  
    } 
    
    @Test 
    public void TestNumber(){ 
        WebDriver drv = getDriver(Language.en); 
        drv.get("http://the-site.com"); 
        WebElement el = drv.findElement //... find element 
        String number = el.getText(); 
        Assert.assertEquals(number, "123.45"); 
        drv.close(); 
        drv = getDriver(Language.de); 
        drv.get("http://the-site.com"); 
        WebElement el = drv.findElement //... find element 
        String number = el.getText(); 
        Assert.assertEquals(number, "123,45"); 
        drv.close(); 
    } 
    
  3. 恐怕你必須關閉瀏覽器並用不同的語言重新打開它。

  4. 我親自爲每個測試創建瀏覽器的新實例。

順便說一句,上面的代碼假設,Web應用程序改變了如何基於瀏覽器語言向用戶顯示數字的方式。

+1

感謝您的回答,可悲的是,這並沒有多大幫助。你說的語言環境只能在操作系統級別進行更改,這是不正確的。您可以在運行時更改Firefox或Chrome中的區域設置,並在下一個請求中更改http標頭中的「accept_languages」。我們的應用程序使用這種語言來選擇文本和格式數字和日期。 – 2012-03-22 17:04:37

+0

其次,每次重新創建瀏覽器實例都很慢。你應該考慮爲此實現一個池。 – 2012-03-22 17:05:22

+1

要在Chrome,Firefox和Internet Explorer中影響「Accept-Language」標題的值,只需更改瀏覽器內的語言設置並在不修改任何操作系統設置的情況下重新加載頁面即可。 – martin 2014-01-30 13:31:16

4

你也可以通過about:config在firefox中做到這一點。但是你需要使用Actions來操作它。

下面一個java的代碼

Actions act = new Actions(webDriver);   

    webDriver.get("about:config"); 

    // warning screen 
    act.sendKeys(Keys.RETURN).perform(); 

    // Go directly to the list, don't use the search option, it's not fast enough 
    act.sendKeys(Keys.TAB).perform(); 

    // Go to the intl.accept_languages option 
    act.sendKeys("intl.accept_languages").sendKeys(Keys.RETURN).perform(); 

    // fill the alert with your parameters 
    webDriver.switchTo().alert().sendKeys("fr, fr-fr, en-us, en"); 
    webDriver.switchTo().alert().accept();