淺析基於Selenium和TestNG的自動化測試框架
互聯網產品迭代迅速,敏捷開發模式逐漸盛行,敏捷開發模式下的敏捷測試需要採用更敏捷的測試流程,在敏捷測試中回歸測試所佔的比重越來越多,而自動化測試是快速實現回歸測試的有效方法。一個項目中自動化測試是否能有效的開展,自動化測試框架是關鍵所在。因此,如何構建穩定的、易復用、易擴展的自動化測試項目對於敏捷測試有重要的意義。
- 面臨的問題
目前互聯網金融火的一塌糊塗, P2P平台的開發測試項目正在如火如荼的進行, Web應用因為其迭代周期短,需求變化快等特殊性質,越來越多的Web開發團隊在擁抱敏捷。同時隨著前端技術JavaScript,Html5,等不斷被推出和完善,Web應用也變得越來越複雜很絢麗。這都給我們的測試帶來了挑戰。
①持續變化的需求導致反覆的回歸測試
②複雜的UI(各種JavaScript的插件,Ajax等)
③往往一個測試團隊需要應付多個項目的測試工作
④非常有限的資源(人力,成本,等等…)
⑤跨平台(Linux,Mac,windows),跨瀏覽器(Firefox,Chrome,IE)
⑥P2P行業的特性,充值提現利息等後台業務數據正確性的驗證非常複雜
- 如何解決
針對前5個問題,ThoughtWorks公司推出的開源Web自動化測試工具Selenium給我們帶來了解決之道。Selenium基於JavaScript並結合其WebDriver來模擬用戶的真實操作,它有很好的處理Ajax的能力,並且支持多種瀏覽器(Safari,IE,Firefox,Chrome),可以運行在多種操作系統上面。
對於第6個問題,則需要UI測試結合介面測試,項目後台主要是基於HTTP協議的restful應用,可以採用spring mvc測試框架通過服務端測試和客戶端測試來解決。下文重點闡述筆者在使用Selenium WebDriver+TestNG測試框架解決前5個問題UI自動化測試的使用經驗和思想。
話說Selenium只是幫我們解決了執行層面的問題,在大規模的自動化測試項目中,我們還需要一個基於Selenium平台的測試框架,這個框架需要有以下的特性。
√ 對象庫的分離和管理
√ 支持數據驅動(DDT)
√ 自動化測試腳本的組織和管理
√ 腳本的可重用(團隊)和可配置
為實現上面的需求,可以參考Google內部使用的一個基於Selenium的Web自動化測試框架Ringo,如下圖所示,從Ringo的架構中可以看出,Ringo實現了數據,對象,操作的3者完全分離。並且對於一些公共的腳本進行了抽取和重構(SeleniumHelper),代碼的復用率非常高。所有的測試用例都是可配置化。
- 框架思想
可以參考上面的框架通過對Selenium進行二次開發並結合TestNG實現數據驅動和高度可配置化,並且具備很好的對象庫的管理的功能,做出一個比較成熟的測試框架。這裡不包含實現DataGenerator,測試數據隨機生成還有待研究,只討論從數據文件讀取測試數據。
首先我們可以通過對selenium提供的API方法進行二次封裝來避免每次對這些方法的直接調用,通過方法的封裝可以防止重複編寫常用方法,還能實現復用,並且易於維護。
接著對這些方法類進行分層組織,而不是統統的堆到一起。比如分為Page類Window類,Element類,Action類等。
然後按照MVC模式的思想將測試項目分模塊,以便控制與數據與測試用例分離,在對象包中放入所有測試用到的頁面包括Page類和Window類,Element類,在數據包中放入各個頁面的元素信息文件,即其ID,XPath等信息,還有測試數據。在用例包中放入測試用例的內容。
- 框架實現
對象庫的分離和管理- Page類和Element類
對象庫包括頁面對象和元素對象,比如zhihu的登陸頁面是一個頁面對象,每個頁面的元素,也可以封裝成一個個元素對象。如果你封裝了頁面,封裝了元素,再封裝一個對應的登陸Action,你的每個測試用例是調用的login.action()。這樣,你只需要改變你對象庫的內容就完美解決UI變化,而不必一個個修改測試用例。
Element類:
Element類就是我們常用的driver.findElement()的形式,就是元素類,什麼是元素類呢?元素就是我們需要定位的那些東西,我們在操作過程中很難知道一個findElement到底查找的是什麼,因為所有的標籤形式都是通過id,xpath或者各種各樣的定位方式來實現的。
如果把各種各樣的findElement都統統的放在一起,造成的腳本難以理解讓後續接手的腳本開發人員可能頭疼不已,所以要進行元素查找的封裝。
Element類提供了所有的關於element的方法,比如滑鼠事件和鍵盤事件,還有更重要的元素定位方法。定位的方法在這裡不做任何的推薦,因為每個人的思路不同,實現的方式也不同,我比較偏向的做法是做一個property文件來進行資源的管理,把所有需要的資源都放入到property裡面,這樣我們就可以進行元素的定位了。並且在後期維護中主要維護property就可以進行對整個腳本進行維護了,不需要我們大量的重新進行源碼的分析和修改了。
當然設計有優化過程,我們可以通過map的方法作為屬性值來進行元素的管理,他的各種定位方法存放在map中,我們需要的時候只需要調一下就可以了。
其實通過xpath的方式我們就可以基本上定位大多數的元素。剩下的內容就是我們對element內容的擴充了。我們可以把元素的更加具體的抽象出來,比如我們把select,table,checkbox等等等的各種html標籤元素顯式的定義出來,在我們定義一個元素的時候我們能夠更加清晰的看到這個元素的含義,我們知道它是一個按鈕或者table等等等。
Page類:
我們知道pageObject的思想是把資源都放入到我們定義的page類裡面,所以這個時候我們需要思考了,我們如何設計這裡的page類呢?按照pageObject的思想來看,page類應該是我們自己編寫的,那樣我們的框架是不是就可以放棄編寫page類了呢?直接封裝一些通用的方法?顯然是不對的,對於頁面html源碼操作的過程中,我們煩透了這些元素查找的硬編碼方式,在一個case裡面或者兩個case裡面反覆的調用編寫是讓人頭疼的一件事情,所以我們可以把所有的單頁面看做一個層次,裡面和PageObject的思想一樣,就是放入了通用的方法,比如獲取title,元素是否出現,某些action等.可以把page類當作一種資源來處理,我們所有需要的東西都是通過page來獲取的。
封裝對象還應包括Driver類和Brower類,之前的點融黑幫文章有過介紹不再累述。
接下來以這個登陸為例。
首先封裝一個BasePage的類,畢竟所有的頁面都有共同的東西,每個頁面都有元素,每個頁面元素都有相應的方法,比如type,click,getElement,isElementPresent,getLocator等。這裡不再貼圖佔用篇幅。
接下來封裝元素,Webdriver的元素,每個元素都有相應的定位地址(xpath路徑或css或id)等待時間和定位類型,默認為By.xpath。
接下來就是登陸頁面的類
接下來就是登陸的action
進入用戶中心的action
到此為止,已經封裝完畢。接下來就能在測試用例直接調用著。
其他類-數據參數化等
我們使用QTP的過程中我們經常會用到參數化,我們自動化的設計都有了,但是沒有參數化的功能怎麼辦?我們應該先想像一下數據提供的方式。TestNG提供了一種參數化的形式,但是它是需要在xml裡面配置或者硬編碼的形式來進行編寫。不過它提供了一種DataProvider的方式來進行參數化,它傳遞參數的形式是Object[][],我們可能希望使用參數的時候通過excel表格來完成,這些都是可以實現的,poi包,jxl包提供了解析excel的功能,非常的強大。具體實現不再多說。
通過這些層次的分析我們已經出現一個框架的雛形了,然後我們剩下的設計就是基於完善和優化了。比如test case運行結束的結果報告和分析,日誌的實現等。
推薦閱讀: