Selenium概述
Selenium是一種Web應用的自動測試工具,經過模擬用戶對Web頁面的各類操做,能夠精確重現軟件測試人員編寫的Test Cases步驟。Selenium包含三個工具:Selenium-IDE,Selenium-RC以及Selenium-Core。其中,Selenium-Core是驅動Selenium工做的核心部分,做爲一個用JavaScript編寫的測試引擎,它能夠操做Web頁面上的各類元素,諸如:點擊按鈕、輸入文本框,以及斷言Web頁面上存在某些文本與Web元素等。
Selenium-IDE是一個Firefox插件,可以錄製回放用戶在Firefox中的行爲,並把所記錄的Selenese(Selenium Commands)轉化爲Java/C#/Python/Ruby等語言,在Selenium-RC中修改複用。對於較爲複雜的Test Cases,Selenium-IDE的功能有限,每每用它錄製大體的步驟,再轉化爲測試人員熟悉的編程語言,在此基礎上完善,造成更爲強大且靈活的Selenium-RC Test Cases。
Selenium-RC(Selenium Remote Control)在Web瀏覽器與須要測試的Web應用間架設代理服務器(Selenium Server),使得JavaScript引擎與被測Web應用同源,繞開同源策略的限制(Same Origin Policy),進而取得對Web頁面進行各類操做的權限。html
開發環境配置
以Java做爲 測試用語言爲例,在Eclipse中新建一個Java項目Test Search Engine,下載Selenium-RC軟件包,把selenium server/selenium java client driver的Jar以及JUnit庫加入到該項目的Java Build Path。java
圖1.Build Path配置web
啓動Selenium-Server,能夠在命令行中使用java-jar命令直接運行可執行Jar包(對於中文Windows操做系統且使用IBM JDK,還須要加參數-Dibm.stream.nio=true)。若是想在Java程序中啓動/中止Selenium-Server,首先,新建一個RemoteControlConfiguration對象rcc,並指定遠程控制參數(包括配置Selenium Server的監聽端口,Firefox瀏覽器的Profile等),而後新建一個SeleniumServer對象,把rcc傳入SeleniumServer的構造函數(對於中文Windows操做系統且使用IBM JDK,在Eclipse的Run Configurations的VM arguments中加入-Dibm.stream.nio=true)。
清單1.使用Java啓動/中止Selenium Server
RemoteControlConfiguration rcc=new RemoteControlConfiguration();
rcc.setPort(4444);//指定Selenium Server開放端口
SeleniumServer SELENIUM_SERVER;
SELENIUM_SERVER=new SeleniumServer(rcc);
SELENIUM_SERVER.start();//啓動server
//測試代碼
SELENIUM_SERVER.stop();//中止server
此外,Selenium Server還能夠經過Ant腳原本控制啓動/中止,這提供了另外一種靈活而強大的項目控制方式。
清單2.使用Ant腳本啓動/中止Selenium Server
在Selenium-Server啓動後,創建一個Selenium類的實例selenium,並經過這個實例與Selenium-Server進行交互,方法以下。
清單3.Selenium實例的啓動/中止
Selenium selenium=new DefaultSelenium(java.lang.String serverHost,
int serverPort,
java.lang.String browserStartCommand,
java.lang.String browserURL);
selenium.start();
//經由selenium控制瀏覽器模擬各類用戶操做
selenium.stop();
Selenium實例包含豐富接口,能夠對各類Web元素進行各類操做。例如,在谷歌頁面中輸入「developerWorks」,點擊搜索按鈕,在結果頁面中驗證是否包含「developerWorks中國」字樣等。
清單4.Selenium測試的簡單示例
Selenium selenium=new DefaultSelenium( "localhost",4444,"*firefox",
"http://www.google.cn");
selenium.start();//啓動瀏覽器
selenium.open( "/");//打開www.google
selenium.type( "q","developerworks");//輸入文本框
selenium.click( "btnG");//點擊搜索按鈕
selenium.waitForPageToLoad( "30000");//等待加載結果頁面
verifyTrue(selenium.isTextPresent( "developerWorks中國"));//驗證是否存在指定字符
selenium.stop();//關閉瀏覽器編程
當Selenim遇到TestNG
用Selenium 測試Web頁面時,所重現的各類行爲依賴於測試人員的輸入參數,例如:選擇下拉餐單的項目,在文本框中輸入字符等。不一樣的測試用例對應不一樣的輸入,如有方法可以簡單有效的傳入測試用參數,會大大提升測試用例的複用性和可 維護性。當Selenium遇到TestNG,這些就能夠實現。TestNG中的NG,意爲Next Generation,事實上,該測試框架引入了很多新特性:靈活的測試配置,支持JDK 5註釋,支持數據驅動的測試,強大的執行模型等。瀏覽器
繼續上文谷歌搜索的場景,經過實例來了解TestNG的用法與功能。
清單5.TestNG應用示例
@Parameters({"url","query-string","btn-id","txt-id","verify-String"})
@Test
public void testGoogle(String url,String queryString,String btnID,
String txtID,String verifyString){
selenium=new DefaultSelenium("localhost",4444,"*firefox",url);
selenium.start();
selenium.open("/");
selenium.type(txtID,queryString);
selenium.click(btnID);
selenium.waitForPageToLoad("30000");
verifyTrue(selenium.isTextPresent(verifyString));
selenium.stop();
}
上面的代碼清單中,註釋Parameters指定的參數在TestNG測試框架的配置文件testng.xml裏有具體定義,以下所示:
清單6.testng.xml示例
不難想到,只要修改testng.xml中的參數值,就能由輸入參數驅動不一樣的測試用例。然而,僅僅在testng.xml中指定參數有很大的侷限性,顯然過多的參數會難以維護,沒法層次分明地組織分屬不一樣Test Cases的輸入。在下文中,咱們來解決這個問題。
回頁首
基於Selenium的分層測試框架
做者在工做中,測試基於OSGi平臺的多個插件。每一個插件實現特有的功能,有多條測試路徑須要覆蓋,同時,各個插件之間又有共通之處,能夠抽取某些部分進行復用。對此,咱們假設這樣的場景:分別在谷歌、百度和必應中搜索各類關鍵字,並在返回的結果頁面中驗證是否存在目標字符串。每一個搜索引擎均可以視爲一個待測的組件,分別爲它們撰寫Test Cases,並組織成一個Test Suite,用於執行測試。事實上,3個搜索引擎的測試因爲同質性,還可以合併爲一種測試,用不一樣的輸入參數來指定所要測試的那個搜索引擎。這裏視爲三個組件,只是爲了說明如何在Selenium+TestNG環境中組織多個測試模塊。
自上而下地考慮,上段描述的測試場景可以進行分解。Test Suite包含三類Test Cases(谷歌、百度與必應),每類Test Cases的一個Test Case由若干可複用的Test Tasks組成,經過傳入不一樣的參數,Test Task完成同質的不一樣行爲。在Test Task之下,定義相關文件,包含待測試的Web頁面元素的定位信息。所以,分層Selenium框架有三個層次:
appObjects——Web頁面元素定位信息,如按鈕與文本框等;
tasks——測試步驟中可複用的行爲;
test cases——由tasks組成的測試用例。
Web元素locators定義與收集
Selenium根據XPath來定位Web元素,XPath的相關知識不屬於本文的內容。前面例子中,在TestNG的配置文件testng.xml裏定義文本框與按鈕的locators,對於複雜的測試場景而言,這不是好的實踐。所以,咱們在appObjects層創建文件,將Web頁面元素locators納入,便於維護使用。Selenium-IDE的Find功能適於完成這一步驟。文件googlePages.properties的內容以下:
清單7.locators文件示例
#define the keys and corresponding XPaht locators of google page.
googleSearchTxtField=//input[@name='q']
googleSearchBtn=//input[@name='btnG']
這時,在testng.xml中,刪去locators相關的parameters,只須要解析.properties文件,生成locators的properties備用。在所附的源碼中能夠看到.properties文件的解析器PropUtils的簡單實現。服務器
測試任務分解與實現
爲說明任務分解,以簡單的搜索過程爲例,能夠分爲輸入搜索關鍵字、點擊搜索按鈕、以及驗證結果頁面。實際代碼以下所示,不難發現,由參數決定行爲方式的 測試任務,都接受一個paraMap數據結構,並根據其內容在方法內採起適當的行爲。經過這種方式,test cases可以以參數配置文件來驅動測試任務實施其想要的行爲。
清單8.Test Task代碼示例
public void openSite(){
selenium.open( "/");
}
public void typeSearchTxtField(HashMap paraMap){
utils.waitForElement((String)elemMap
.get(TestGoogleConstants.GOOGLE_SEARCH_TXT_FIELD),30);
selenium.type((String)paraMap
.get(TestGoogleConstants.GOOGLE_SEARCH_TXT_FIELD),
(String)elemMap
.get(TestGoogleConstants.GOOGLE_SEARCH_TXT_FIELD));數據結構
}
public void clickSearchBtn(){
utils.waitForElement((String)
elemMap.get(TestGoogleConstants.GOOGLE_SEARCH_BTN),30);
selenium.click((String)elemMap.get(TestGoogleConstants.GOOGLE_SEARCH_BTN));
}
public void verifyResult(HashMap paraMap){
stc.verifyTrue(selenium.isTextPresent((String)
paraMap.get(TestGoogleConstants.VERIFY_STRING)));
}
clickSearchBtn方法無需參數輸入,由於其任務只是點擊搜索按鈕,在test cases須要時調用便可。這裏只是以一個簡單的例子說明如何分解任務,對於實際的test case,這個過程會複雜許多,但其後的複用與靈活調用徹底值得這些工做的付出。
Test Cases實現與Test Tasks調用
Test Cases做爲一系列測試步驟的集合,能夠經過調用若干Test Tasks實現。以貫穿本文的搜索引擎爲例,以此調用上一部分定義的test taskss,重現整個測試過程。簡單代碼以下所示。
清單9.Test Case代碼示例
@Parameters({"google_se_para_1"})
@Test
public void testGoogle_1(String paraFile){
paraMap=(HashMap)XMLParser.getInstance()
.parserXml(paraFile);
tgTasks.openSite();
tgTasks.typeSearchTxtField(paraMap);
tgTasks.clickSearchBtn();
tgTasks.verifyResult(paraMap);
}
Test Cases在分層Selenium測試框架下,就是按照要求調用已有的Test Tasks。值得注意的是,在上面兩個代碼列表裏的paraMap參數。這個哈希表由咱們實現的解析器解析參數定義文件而獲得。TestNG的Parameters參數機制,使得Test Cases可以靈活地指定參數文件,從而驅動不一樣的Test Cases。
清單10.參數定義文件示例
developerworks
developerWorks中國
創建輸入參數解析器(parser)及參數文件
Test Cases與Test Tasks的順暢工做,須要輸入參數文件及對應的參數解析器的配合。咱們以上面代碼清單的例子說明參數文件的格式。標籤在最外層,其內的子元素爲具體的參數值,如標籤表示一個頁面元素與其對應的輸入。元素的id屬性與清單6中的.properties文件定義的locators對應,而其子元素則表示該locator的輸入值。解析器的具體實現能夠參見所附的示例源代碼。
回頁首
導出可執行Jar包以部署到各種測試服務器
爲了可以把Selenium測試腳本導出成一個可執行Jar包,咱們能夠把testng.xml中定義的相關內容,在Java代碼中實現,以下所示。
清單11.testng.xml的Java表示
//suite tag
XmlSuite suite=new XmlSuite();
//set suite name
suite.setName("Test Search Engine");
//set parameter tag
HashMap para=new HashMap();
para.put("google_se_para_1","/src/resources/google_se_para_1.xml");
suite.setParameters(para);
//test tag
XmlTest testGoogle=new XmlTest(suite);
testGoogle.setName("LDAP configuration template");
List classes=new ArrayList();
classes.add(new XmlClass(TestGoogleTestCase.class));
testGoogle.setXmlClasses(classes);
這份代碼列表的功能與前文的testng.xml徹底相同,把這些代碼添加到新定義的類SearchEngineSuite的main函數中,在這個類的方法中啓動並關閉Selenium服務器,並把相關文件打成一個可執行Jar,就能夠經過命令行的java–jar命令,執行Selenium測試。固然,由於具備通用性,也能夠部署到各種測試服務器,執行測試。
這裏推薦使用Eclipse的插件Fat Jar導出runnalbe Jar。首先,填入輸出Jar的命名,並把SearchEngineSuite設置爲Main-Class。而後,勾選」merge individual-sections of all MANIFEST.MF files」,後一項視需求勾選。app
圖2.Fat Jar導出步驟1框架
進入下一步,選擇要導出的文件,包含源代碼以及用到的Jar文件,點擊完成便可。編程語言
圖3.Fat Jar導出步驟2
導出後的runnable Jar,使用命令java–jar TestSearchEngine_fat.jar運行便可。
結束語
通讀本文不難發現,Selenium提供了一種Web 測試的新方法,在分層框架的支持下,其功能更爲強大,運用靈活,有很強的複用性。經過指定不一樣的參數文件,本文的例子能夠對Google進行不一樣關鍵字的測試驗證,一樣的方法能夠應用於百度與必應。並經過testng.xml或者其Java代碼形式整合爲一個Test Suite運行。在所附源代碼中能夠看到詳細的實現。在做者的實際工做中,複雜的測試需求也能應付自如。
本文選自:http://www.spasvo.com/ceshi/open/kygncsgj/Selenium/2014128164908.html