1. 基於對象的測試
1.1 Selenium 2構成
Selenium 2是一種用於Web應用程序的自動測試工具,它提供了一套友好的API,自身就是一套類庫,不依賴於任何測試框架,不需要啓動其他進程或安裝其他程序,也不用像Selenium 1那樣需要先啓動服務。
Selenium 2針對各個瀏覽器而開發,它取代了嵌入到被測Web應用中的JavaScript,與瀏覽器緊密集成,支持創建更高級的測試,避免JavaScript安全模型限制,除此之外,Selenium 2還利用操作系統級的調用模擬用戶輸入。WebDriver支持Firefox、IE、Opera、Chrome,還支持Android和iPhone的移動應用測試。
1.2 基於對象
Selenium 2與Selenium 1存在明顯差異,儘管它們都屬於瀏覽器自動化的API,但對於用戶來說,Selenium 1提供的更多的是基於方法的API,所有方法都一個類中開放,而Selenium 2的API則面向對象,不同的對象擁有不同的操作方法,例如:
#Selenium 1 public class Main { public static void main(String[] args) { DefaultSelenium selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "http://www.baidu.com"); selenium.start(); selenium.open("selenium.typeKeys(@"//input[@id='kw']","Tester"); selenium.click(@"//input[@id='su']"); } }
#Selenium 2 public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword = driver.findElement(By.id("kw")); WebElement search = driver.findElement(By.id("su")); keyword.sendKeys("Tester"); search.click(); } }
1.3 選擇瀏覽器
要開始測試前,首先得創建Selenium的實例,也就是對應的Driver,對於Firefox、IE、Chrome,只需在電腦中安裝相應的瀏覽器就可以開始測試了。而對於Android和iPhone,它們在測試前需要安裝支持軟件,以Firefox爲例,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); } }
2. 開始測試
2.1 瀏覽器導航對象
在Selenium 2中,要導航頁面,需要用到Navigation對象,可以通過WebDriver的navigate()方法獲得Navigation對象實例,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); } }
在獲得該對象後,就可以執行跳轉到指定URL、前進、後退、刷新頁面等操作。在JAVA中,可以使用to()來進行跳轉,只需將URL作爲參數即可,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); } }
在瀏覽器上,可以按前進和後退按鈕來進行導航,通過back()/forward()方法,也可以實現這種導航功能,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); navigation.to("http://www.google.com.hk"); navigation.back(); navigation.forward(); } }
使用refresh()方法將刷新整個頁面,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); navigation.refresh(); } }
2.2 查找條件對象
在對頁面上元素操作之前,需要找到相應的元素,可以使用查找條件對象By進行查找。查找可以按照HTML元素的ID或Name屬性進行,或按照HTML標籤,其中最常使用的是查找ID屬性,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement search = driver.findElement(By.id("su")); } }
與ID類似,name()方法按照Name進行查找,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement search = driver.findElement(By.name("wd")); } }
linkText()方法按鏈接文本進行查找,而partialLinkText()方法按鏈接文本進行模糊查找,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement login1 = driver.findElement(By.linkText("登錄")); WebElement login2 = driver.findElement(By.partialLinkText("登錄")); } }
className()方法按元素的class屬性進行查找,tagName()則按標記名稱進行查找並返回第一個匹配項,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword1 = driver.findElement(By.className("s_ipt")); WebElement keyword2 = driver.findElement(By.tagName("input")); } }
如果以上方法都無法定位,可以按xpath()進行查找,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement search = driver.findElement(By.xpath("//input[@id='su']")); } }
2.3 操作頁面元素
可以通過WebDriver的findElement()方法獲得WebElement的對象實例,在獲取頁面元素後,就可以對該頁面元素進行各種操作了。
click()方法用於執行單擊元素的操作,sendKeys()方法用於給input元素輸入文本,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword = driver.findElement(By.id("kw")); WebElement search = driver.findElement(By.id("su")); keyword.sendKeys("Tester"); search.click(); } }
clear()方法用於清空input元素的值,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword = driver.findElement(By.id("kw")); keyword.sendKeys("Tester"); keyword.clear(); } }
submit()方法用於對指定元素所在的form元素進行提交操作,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword = driver.findElement(By.id("kw")); WebElement search = driver.findElement(By.id("su")); keyword.sendKeys("Tester"); keyword.submit(); } }
2.4 獲取頁面及頁面元素內容
在跳轉到某個頁面或獲取某個頁面元素之後,除了對其進行操作,還可以獲取它的內容。比如getTitle()方法用於返回當前網頁的標題,getCurrentUrl()方法用於獲取當前網頁的URL,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); String title = driver.getTitle(); String url = driver.getCurrentUrl(); } }
getText()方法用於存儲某個元素的文本值,例如鏈接、純文本等,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement link = driver.findElement(By.name("tj_login")); String text = link.getText(); } }
isSelected()方法用於存儲複選框或單選框的勾選情況,返回值爲true或false,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement link = driver.findElement(By.name("tj_login")); link.click(); WebElement checkbox = driver.findElement(By.id("TANGRAM__PSP_8__memberPass")); boolean isSelected = checkbox.isSelected(); } }
getTagName()方法用於獲取元素的標記名稱,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement link = driver.findElement(By.name("tj_login")); String tagName = link.getTagName(); } }
isEnabled()方法用於存儲input等元素的可編輯狀態,isDisplayed()方法用於驗證元素是否在頁面上顯示,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword = driver.findElement(By.id("kw")); boolean isEnabled = keyword.isEnabled(); boolean isDisplayed = keyword.isDisplayed(); } }
getAttribute()方法用於獲取指定屬性的值,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement keyword = driver.findElement(By.id("kw")); String value = keyword.getAttribute("value"); } }
3. 測試處理
3.1 彈出對話框處理
JavaScript共有3種彈出對話框:Alert、Confirmation以及Prompt,Selenium 1使用的是JavaScript注入的方式來進行測試,所以無法直接處理對話框,而Selenium 2是針對各個瀏覽器開發的,避免了JavaScript安全模型導致的限制,因此對話框會成功彈出。
在Selenium 2中,彈出對話框統一視爲Alert對象,只需調用Alert對象的方法即可。Accept()方法單擊彈出對話框的確認按鈕,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement btn = driver.findElement(By.id("getAlert")); btn.click(); driver.switchTo().alert().accept(); } }
dismiss()方法單擊彈出對話框的取消按鈕,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement btn = driver.findElement(By.id("getAlert")); btn.click(); driver.switchTo().alert().dismiss(); } }
sendKeys()方法在彈出對話框中輸入文本,該方法只對Prompt彈出對話框有效,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement btn = driver.findElement(By.id("getAlert")); btn.click(); driver.switchTo().alert().sendKyes("Hello World"); } }
getText()方法用於獲取彈出對話框的文本內容,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement btn = driver.findElement(By.id("getAlert")); btn.click(); string text = driver.switchTo().alert().getText(); } }
3.2 多窗口處理
在進行Web測試時,還會彈出一些子窗口,並在多個窗口之間進行切換。要在多個窗口之間進行切換,首先必須獲取每個窗口的唯一標識符(句柄),通過getWindowHandles()方法可以獲取所有打開窗口的標識符,並將其以集合的形式返回,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); String[] handles = new String[driver.getWindowHandles().size]; driver.getWindowHandles().toArray(handles); for (int i = 0; i < handles.length; i++) { System.out.println(handles[i]); } } }
新窗口彈出後,可以通過它的標識符(句柄)切換到該窗口,再對該窗口的元素進行操作,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement loginLink = driver.findElement(By.name("tj_login")); loginLink.click(); WebElement regLink = driver.findElement(By.className("pass-reglink")); regLink.click(); String[] handles = new String[driver.getWindowHandles().size]; driver.getWindowHandles().toArray(handles); driver.switchTo().window(handles[1]); } }
3.3 設置管理
在Selenium2中,可以通過Options對象對測試進行設置,包括Cookie、超時時間和瀏覽器窗口等。通過getCookies()方法可以獲取當前的Cookie集合,可以對其進行讀取、添加和刪除,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); java.util.Set<Cookie> cookies = driver.manage().getCookies(); Cookie[] allCookies = new Cookie[cookies.size()]; cookies.toArray(allCookies); java.util.Calendar calendar = java.util.Calendar.getInstance(); calendar.add(java.util.Calendar.Date, +1); java.util.Date date = calendar.getTime(); Cookie newCookie = new Cookie("newcookie", "value", "baidu.com", "",date); cookies.add(newCookie); cookies.remove(allCookies[cookies.size()-1]); } }
通過window()方法可以對當前的窗口進行簡單的控制,如查看窗體的座標和大小,並最大化,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); Window window = driver.manage().window(); System.out.println(window.getPosition().x); System.out.println(window.getPosition().y); System.out.println(window.getSize().width); System.out.println(window.getSize().height); window.maximize(); } }
timeouts()方法會獲得Timeouts對象,它包含3種方法,implicitlyWait()方法設置腳本在查找元素時的最大等待時間,setPageLoadTimeout()方法設置頁面操作超時時間,setScriptTimeout()方法設置腳本異步執行的超時時間,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); Timeouts timeouts = driver.manage().timeouts(); timeouts.implicitlyWait(30, java.util.concurrent.TimeUnit.SECONDS); timeouts.setPageLoadTimeout(30, java.util.concurrent.TimeUnit.SECONDS); timeouts.setScriptTimeout(30, java.util.concurrent.TimeUnit.SECONDS); } }
3.4 結束測試
當測試執行完畢後,有兩種方法可以結束測試,一種是使用close()方法關閉WebDriver當前所在的窗口,另一種是直接使用quit()方法關閉所有窗口,例如:
public class Main { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); Navigation navigation = driver.navigate(); navigation.to("http://www.baidu.com"); WebElement loginLink = driver.findElement(By.name("tj_login")); loginLink.click(); WebElement regLink = driver.findElement(By.className("pass-reglink")); regLink.click(); String[] handles = new String[driver.getWindowHandles().size]; driver.getWindowHandles().toArray(handles); driver.switchTo().window(handles[1]); driver.close(); driver.switchTo().window(handles[0]); driver.quit(); } }