【IT168 技術】Selenium是時下很流行的面向web的自動化測試工具,它以執行效率高,覆蓋的瀏覽器普遍等優勢獲得了不少人的親睞。TestNG是一款測試 框架,它派生自JUnit和NUnit,除了繼承了二者的優點以外,又額外的發展出了一些新的功能,讓其更增強大和易用。文章會重點介紹 Selenium2結合TestNG如何作自動化測試,另外也會介紹ReportNG,它是對TestNG report的一個擴展,它相較於TestNG自身的report而言,更加美觀和易讀。javascript
利用Selenium實現web自動化測試的優點css
相比QTP,RFT昂貴的成本,做爲開源工具的Selenium WebDriver天然不用多說。並且selenium是一款基於瀏覽器的測試工具,所以在響應UI請求時運行速度比較可觀,能很好的節省運行時間,提升 執行效率。在與大多數測試平臺的整合以及可擴展的腳本語言種類上(Java、dotNET、Perl、Python、Ruby、C#等)較之其餘工具也有 很大優點,最後,Selenium 支持多瀏覽器操做(IE,Firefox,Safari ),這也是其餘測試工具所不具有的,固然,沒有什麼萬能的測試工具,在全面評估被測系統和測試需求後,合適的就是最好的;並且在作自動化測試過程當中,每每 不能只單獨使用一種自動化工具,結合不一樣自動化工具的優點來達到咱們的目的是最佳的實踐。html
Selenium的進化java
Selenium已經從以前的1.0(RC)進化到了如今的Selenium2(Selenium1+WebDriver)。web
在運行Selenium1.0程序以前,咱們必須啓動Selenium server端,也就是Selenium Remote control,咱們簡稱RC,RC主要包括三個部分,launcher,http proxy,selenium core, 其中selenium core是由一堆javascript函數構成,經過調用這些函數,來實現對瀏覽器的各類操做。既然已經能夠實現對瀏覽器的操做,那爲何還須要 Selenium2(Selenium1+Webdriver)呢? Selenium1主要存在如下幾個缺點1.沒有原生的鼠標和鍵盤事 件;2.XSS/HTTP同源數據問題;3.popup dialog問題。Webdriver對不一樣瀏覽器的處理和Selenium1.0有着明顯的不一樣,Selenium1.0不論是什麼瀏覽器,都是由 javascript來處理,而webdriver是選擇瀏覽器最容易識別的語言來處理,好比在Firefox中javascript最容易,在IE中 C++最容易識別,經過靈活選擇最容易識別的語言來處理多瀏覽器,咱們就能夠很好的迴避某些瀏覽器對javascript的安全限制,Webdriver 不只能夠處理這方面的問題,並且能夠調用操做系統API,尤爲是當用戶須要模擬鼠標或鍵盤操做時,這項能力的做用表現的尤爲明顯。經過對比, 看來從Selenium1.0進化到Selenium2.0仍是頗有必要的。瀏覽器
利用Selenium web driver實現自動化測試安全
爲了讓整個文章更加充實,做者以一個簡單的Scenario爲例,來一步一步告訴讀者如何利用Selenium WebDriver+TestNG+ReportNG來實現web自動化。注:該Scenario會貫穿整個文章。框架
Sample Scenario:dom
簡要描述: 在Jazz.net上提問模塊化
步驟:1.打開Jazz.net: https://jazz.net/
2.點擊Log in鏈接
3.以某用戶名登陸
4.輸入密碼
5.點擊Log In button
6.驗證Profile Image是否出現
7.點擊Forum鏈接
8.點擊Ask a question按鈕
9.在提問頁面填寫全部必填域,提交問題
10. 驗證問題是否提交成功
11. Log out
1. 爲了快速產生一個自動化腳本,咱們能夠利用Selenium IDE來錄製原始的腳本,而後根據須要把腳本Refine成爲易於維護的版本(固然,若是你對Selenium的web driver的API很熟悉,而且有一個很好的測試框架能夠採納,也能夠直接寫腳本)。Selenium IDE是一個Firefox add-on,易於安裝和使用,這裏不作介紹,只附一張經過Selenium IDE錄製上面的sample scenario的截圖,圖1:
錄製完成以後,將其導出成Java/JUnit4/WebDriver格式(圖2),而且命名爲PostAQuestionInJazzDotNet。
2. 在Eclipse IDE中創建一個Java project,創建以下的文件夾結構,圖3
將剛導出的PostAQuestionInJazzDotNet.java放入cases文件夾,data文件夾用來存儲腳本中須要用到的數據,map 文件夾中用來存儲腳本中用到的對象的屬性信息,lib文件夾中用來放置所須要的依賴jar包。目前須要將selenium web driver相關的jar包放入到lib中,而且加入到build path中。
打開PostAQuestionInJazzDotNet.java,修復編譯錯誤,例如將包名修改成cases,如圖4:
▲圖4 經過Selenium IDE導出的JUnit格式的java腳本
修復編譯錯誤後的腳本應該已經能夠運行,但基於如下緣由,咱們須要對腳本重構:
a. 錄製出來的腳本易讀性通常。
b. 數據/對象屬性與測試邏輯混爲一體,不便於維護。
c. 導出的腳本是基於JUnit的,咱們須要修改成TestNG的。
3. 重構腳本
3.1 將測試數據從測試邏輯中分離,也即參數化數據。
咱們採用csv做爲存儲數據的格式,如圖5所示:(截圖爲經過Excel打開的顯示的樣式)
▲圖5 以CSV格式來存儲數據
第一行爲每一個數據項指定一個邏輯的名字,以逗號分隔,從第二行起,在對應的數據列中填上腳本中要用到的數據值,支持多行數據的存儲,便於之後實現數據驅動。
建立DataHelper類,用於從數據文件中獲取數據。
其中包含的主要方法有:
initFullAppData,用於將數據讀入內存,代碼片斷以下:
▲圖6 initFullAppData代碼片斷
getAppData,用於根據數據項的邏輯的名字讀取出某行的值,代碼片斷以下:
▲圖7 getAppData代碼片斷
在腳本中能夠這樣使用:
在setUp方法中調用:DataHelper.initFullAppData(this, projectPath, cassName);
而後在其餘測試方式中能夠直接經過 DataHelper.getAppData("PostAQuestionInJazzDotNet_data:JazzURL",1);得到數據值, 其中第一個參數是數據項的全名,第二個參數是該數據項的第幾個值(這點是爲了考慮作iteration,也即數據驅動測試所設置的)
3.2 將web上的元素的屬性值從測試邏輯中分離
這裏須要瞭解一下Selenium如何查找定位web元素。
By.id
By.cssSelector
By.linkText
By.name
By.xpath
By.partialLinkText
經過以上的locator能夠看出來Selenium支持利用多種屬性定位,那咱們須要將對象的屬性存儲在獨立的文件中,便於維護和重用,所以咱們以以下的xml的格式來存儲元素的屬性值,以下圖:
▲圖8 用XML格式來存儲對象屬性
其中,例如 LoginLink爲對象的邏輯名稱,能夠由測試人員本身定義;propertyName來指定用何種方式來定位元素,可選的值包括:id, name, link, dom, xpath, css, partiallink;value用來存儲屬性值。
建立AutoObjectFactory類來管理對象屬性文件,代碼片斷以下:
▲圖9 AutoObjectFactory代碼片斷
在腳本中能夠這樣使用:
在case中定義:private AutoObjectFactory factory = AutoObjectFactory.createInstance(
"PostAQuestionInJazzDotNet_map.xml", projectPath
+ File.separator + "map");
而後在測試方法中經過:WebElement element = factory.getWebElement("PostAQuestionInJazzDotNet_map:userName", driver, defaultTimeOut);得到對象,而後調用相應的方法對其進行操做,例如:
element.sendKeys(DataHelper.getAppData("PostAQuestionInJazzDotNet_data:userName",1));
經過兩步分離以後,腳本結構更加清晰,以下圖所示:
▲圖10 兩步分離以後的腳本的代碼片斷
看似測試數據與測試邏輯的分離,對象屬性與測試邏輯的分離,有些額外的efforts要作,但從長遠來講對於腳本的重用,維護都有不少益處,例如:對象 和數據能夠在多個腳本之間公用,若是對象或者數據有變化,只須要在其獨立文件中修改,修改後的內容天然得以在引用它的多個腳本中生效。
結合TestNG讓自動化測試的流程掌控自如
儘管目前的腳本結構已經很清晰,數據和測試邏輯也都分離開來,易於維護,但從測試調度的角度以及可重用的角度來看,還須要進一步改進。
TestNG,即Testing Next Generation,下一代測試技術,是一套根據JUnit 和 NUnit思想而構建的利用註釋來強化測試功能的一個測試框架,既能夠用來作單元測試,也能夠用來作集成測試。
一般編寫一個測試的過程有三個典型步驟:
* 編寫測試的業務邏輯並在代碼中插入TestNG annotation
* 將測試信息添加到testng.xml文件或者build.xml中
* 運行TestNG
在上述段落中咱們的Sample scenario是一個相對長的測試用例,若是是將此用於手動測試,應該不失爲一個好的測試用例,可是用在自動化測試中,咱們指望能夠儘量模塊化咱們的 腳本,以便於之後重用。模塊化以後,咱們就能夠利用TestNG的Annotation指定該模塊什麼時候運行,以及運行順序等,在多個測試用例中也能夠重 用。
從新組織的Sample Scenario以下:
1.打開Jazz.net: https://jazz.net/
2.打開Login頁面
3.輸入有效的登陸數據
4.進入提問頁面
5.填寫提問內容
6.提交提問
7.驗證提交是否成功
8.Logout
在重構腳本且給測試方法添加TestNG的Annotation以前,須要將Junit的Annotation去除掉,而後引入TestNG相關的Jar包:testng-6.*.jar,添加TestNG的Annotation。通過重構後,腳本片斷以下:
▲圖11 添加TestNG的Annotation
利用TestNG的優點,咱們能夠把一些初始化/ 收尾工做的測試方法用@BeforeSuite/@AfterSuite,@BeforeGroups/@AfterGroups, @BeforeTest/@AfterTest等標記, 也能夠用一些屬性控制它是否無論什麼狀況下都執行,定義其依賴的方法等。
例如:
▲圖12 @BeforeSuite的用法
▲圖13 @AfterSuite以及屬性alwaysRun的使用
爲了定義測試的執行順序,須要創建xml文件,定義執行順序。具體的XML中各個節點和屬性的含義請參閱TestNG官方站點。
▲圖14 用於定義執行順序的XML文件
而後在main方法經過TestNG來讀取xml文件以驅動測試的執行,代碼片斷以下:
▲圖15 經過程序調用TestNG
運行測試用例以後,產生的TestNG的report以下:
咱們在充分了解了TestNG的各類Annotation以及如何控制其執行行爲,就能夠把模塊化的測試方法調度的更好,也能夠作到很好的重用。
利用ReportNG生成美觀易讀的測試報告
從上個章節中,咱們能夠看到TestNG有其默認的report,儘管其內容較全面,但不易閱讀,所以咱們想利用ReportNG來替代TestNG默認的report。
ReportNG提供了簡單的方式來查看測試結果,並能對結果進行着色,還能夠經過修改模板定製化內容,修改CSS來替換默認的輸出樣式等。
爲了使用ReportNG,首先咱們要引入reportng-1.1.4.jar和velocity-dep-1.4.jar,或者直接導入有其源代碼,進行定製化。
舉例說明咱們進行的一些定製化的內容:
1. 默認的ReportNG的報告中,是以字母序對執行的方法進行排序的,這不是咱們指望的,咱們指望是以方法的執行前後順序來進行排序的,故修改了TestResultComparator類,以下圖:
▲圖17 TestResultComparator代碼片斷
2. 但願報告中顯示的信息更加詳細,且有截圖,故定製化了模板文件/本地化文件等,如圖:
▲圖18 本地化Properties文件
▲圖19 報告輸出模板文件
3. 在ReportNGUtils中添加截圖的相關方法,以下圖所示:
▲圖20 截圖的相關代碼片斷
4. 在main方法中修改代碼,使得testNG使用定製化後的report做爲報告輸出。
▲圖21 修改Main方法
再次運行該測試用例,獲得的測試報告以下:
Overview
▲圖22 報告的整體預覽
Details
▲圖23 報告的詳細測試結果
截圖能夠放大/全屏觀看,以下圖:
結束語
一套成熟的自動化框架是須要在項目實踐中持續優化的,只有不斷的實踐才能發現問題,解決問題,積累經驗,逐步完善。但願做者提供的這一實踐能夠給讀者一 些借鑑,但這一實踐還遠遠未達到完善的地步,咱們願意和你們一塊兒多思考,多交流,結合本身的項目特性靈活運用,合理改進已達到能真正運用工具解放平常繁瑣 勞動,提升效率,保證質量的效果。
做者簡介
皇甫鵬: IBM CDL高級軟件工程師, QA lead,從事自動化測試工具的設計和開發,以及創新工具的開發等。在Developworks和其餘期刊上發表過多篇文章。
陳宇:IBM GDC 軟件測試工程師,主要從事功能測試,自動化測試
餘新龍: IBM GDC高級軟件測試工程師,主要從事Web自動化測試。