摘要:概述是由有贊開發(fā)的自動化工具,并以此實現(xiàn)了端和端的核心業(yè)務的自動化。旨在簡化開源工具提供的接口,方便自動化測試用例的設(shè)計。元素定位自動化用例其實可以分成兩部分,定位元素調(diào)用接口操作該元素。一臺用于跑自動化用例的服務器。
概述
Bee 是由有贊 QA 開發(fā)的 UI 自動化工具,并以此實現(xiàn)了 web 端和 wap 端的核心業(yè)務的自動化。旨在簡化開源工具提供的接口,方便 UI 自動化測試用例的設(shè)計。
Bee 整個框架是基于 selenium 和 selenide 設(shè)計的。框架對 selenium 和 selenide 提供的接口進行了二次封裝以滿足日常的用例設(shè)計,二次封裝后的接口解決了一些元素加載,元素定位解析等問題,可以讓用例設(shè)計變得更加簡便。
Bee 能支持 Web 和 Wap 頁面的元素定位以及操作,其中 Selenide 主要支持 Web 頁面的元素操作,Selenium 支持 Wap 頁面的元素操作。
Bee 為什么會采用 Selenide+Selenium 的模式。原因一,其實框架設(shè)計的初衷是想全部依賴 Selenide 來完成 Web 和 Wap 的自動化,Selenide 對于作者來說是一個全新的開源框架,很想窺探一二; 原因二,Selenium 可無縫接入。在實踐過程中發(fā)現(xiàn) Selenide 還不能支持 Wap 頁面,滿足不了日常的測試需求,好在框架可以很容易的嵌入 Selenium 從而實現(xiàn)了 Wap 頁面的自動化,也正是 Selenide 和 selenium 有這個特性,所以在框架設(shè)計初期才敢放心的嘗試采用Selenide;原因三,在實踐中的切身體會 Selenide 對頁面元素的處理會比 Selenium 平滑的多,因為 Selenide 其本身也是對 Selenium 的一個二次封裝,對 Selenium 的接口也做了很多的優(yōu)化。
Bee 目前支持的環(huán)境為:mac、chrome,整個框架支持可擴展。
對于 Selenide 和 Selenium 的原理不在本文中贅述,大家可以到網(wǎng)上學習了解。
Bee 開源地址:beeyz,歡迎交流。
按照實際的業(yè)務流程調(diào)用對應接口來實現(xiàn) WEB-UI 自動化測試用例。case 層可調(diào)用 service 層和 pageObject 層的接口,pageObject 是對每一個頁面元素的一個封裝,service 是對一個常用的業(yè)務模塊功能的封裝。比如一個營銷秒殺的測試用例,需要依賴登入、創(chuàng)建商品,這兩個業(yè)務功能就可以直接調(diào)用 service 中的接口。秒殺活動的創(chuàng)建就可以調(diào)用 pageObject 中的接口,然后按照秒殺的業(yè)務流程,在測試用例中把這些接口串起來就形成了一個 UI 自動化測試用例,詳細細節(jié)接下去會舉例說明。
設(shè)計用例的靈活度取決于 pageObject 封裝的顆粒度,顆粒度越小越容易在用例層設(shè)計出新流程的測試用例。用例層使用了 testng,可按照實際的需求靈活設(shè)計一個測試用例。推薦在封裝 pageObject 接口的時候,顆粒度定義的越小越好,方便用例的擴展和維護。pageObject 封裝的接口就相當于一個原子,原子粒度越小越方便組裝成新的用例。相反如果粒度太粗維護上會不太方便。參考代碼:
截圖是一個秒殺用例。創(chuàng)建活動之前,需要登入有贊微商城后臺,登入操作已封裝到 loginService,直接調(diào)用 service 層的接口,不需要在意這個步驟的細節(jié);登入之后要指定一個商品參與秒殺活動,普通商品創(chuàng)建已封裝到 goodsService,直接調(diào)用 service 層的接口,不需要在意這個步驟的細節(jié);接著是創(chuàng)建秒殺活動,創(chuàng)建秒殺活動的所有業(yè)務步驟都封裝到 seckillPage,這就是個 pageObject 的實現(xiàn),也是用例設(shè)計中最主要的環(huán)節(jié)。最后把這幾個步驟串起來就形成了一個秒殺活動的測試用例。用例結(jié)構(gòu)清晰,組裝簡單。
整個工程基于 selenide & selenium,采用 pageObject 模式搭建起來。技術(shù)結(jié)構(gòu):selenide+selenium+testng+reportng+spring。下面對工程中的幾個重要模塊做介紹。
為了實現(xiàn)測試數(shù)據(jù)和測試用例分離而采取的一種方法,數(shù)據(jù)模型在 model 中定義,具體的測試數(shù)據(jù)則在 dataprovider 中初始化。
1.2 driver — 接口層對 web 頁面所有元素的操作都是在這里定義接口并實現(xiàn)的。driver 對 selenide&selenium 提供的接口做了二次封裝,對外提供封裝后的接口。common 實現(xiàn)了一些和接口相關(guān)的公共方法,比如模擬鍵盤按鈕等,目前 common 封裝的方法不多,大多功能都可以通過 selenide&selenium 實現(xiàn)。driver 層對開源工具接口做了二次封裝,想要驅(qū)動一個瀏覽器還有一個必不可少的工具 —— 瀏覽器驅(qū)動,這個驅(qū)動放在 resources 里,驅(qū)動的版本必須與被測瀏覽器版本相匹配。
1.3 listeners — 監(jiān)聽器為了提高框架本身的容錯能力監(jiān)聽一些事件。目前實現(xiàn)了:1. 監(jiān)聽用例測試結(jié)果,可對不同的測試結(jié)果監(jiān)聽器做不同的處理;2. 失敗測試用例重試的監(jiān)聽,一個 fail 的用例最多可重試3次。
1.4 model — 數(shù)據(jù)模型為了實現(xiàn)測試數(shù)據(jù)和測試用例分離而采取的一種方法,具體的測試數(shù)據(jù)在 dataprovider 中初始化。可以對一個業(yè)務流程中需要測試數(shù)據(jù)的元素在一個 model 中定義出來,方便管理和代碼閱讀。
1.5 pageObject — 業(yè)務層pageObject 模式,接口形式封裝每一個頁面需要用到的元素,實現(xiàn)上只要做兩步:確定元素的定位方式;調(diào)用 driver 中對應的操作接口。driver 的接口實現(xiàn)包含了一定的容錯能力,但并不是全面的,有些頁面獨特性或者組件的獨特性單純調(diào)用 driver 的接口并不能保證測試用例的穩(wěn)定性,此時就需要在 pageObject 的接口實現(xiàn)中加入一些容錯算法,確保用例穩(wěn)定性。
實際操作的經(jīng)驗是 pageObject 對元素封裝的顆粒度越小,在用例設(shè)計層設(shè)計測試用例就越靈活,可以像組裝工具那樣組裝出一個新的測試用例。參考代碼:
一個業(yè)務流程很多時候依賴其他業(yè)務模塊功能,為了方便設(shè)計一個測試用例,也為了避免重復造輪子,service 層就提供了一些常用的業(yè)務功能,比如登入、創(chuàng)建商品等。依賴方只需要在 service 層調(diào)用即可。
2、功能優(yōu)化Bee 對 selenide&selenium 做二次封裝的同時也對接口做了些優(yōu)化,框架的初衷是使設(shè)計一個 UI 用例盡可能的易設(shè)計、易讀、易維護。
2.1 接口優(yōu)化直接調(diào)用 selenide 或者 selenium 的接口經(jīng)常會遇到些令人頭疼的問題,比如網(wǎng)絡(luò)問題使頁面 loading 太慢,需要操作的元素還沒展示出來,這種情況就會經(jīng)常報元素找不到的 error,用例執(zhí)行失敗,但實際上這種報錯不是一個 bug,測試結(jié)果是無效的。為了提高誤報率 driver 層接口實現(xiàn)了等待元素加載的功能,使用的關(guān)鍵接口:Selenide.$(elementLocator).waitUntil(Condition.appears, timeout)。參考代碼:
`/** * 檢查元素加載情況 * @param elementLocator * @param timeout * @return */ private boolean checkElementLoad(By elementLocator, long timeout){ try { Selenide.$(elementLocator).waitUntil(Condition.appears, timeout); return true; }catch (Exception ex){ throw new RuntimeException(ex); } } /** * 如果沒有找到元素拋null異常 * @param element * @param timeout * @param elementType * @return */ private By isElementLoaded(String element, long timeout,String ...elementType){ By elementLocator = null; int count = 4; long partTimeout = timeout/count; for(int i=0; i概述中提到過 selenide 本身就是對 selenium 的一個二次封裝,所以 selenide 對元素的操作會比 selenium 平滑的多。在頁面加載方面 selenide 本身有做優(yōu)化,再在 click、input 等操作接口中加入 waitUntil 的判斷可最大限度的等待一個元素的加載從而提高測試用例的穩(wěn)定性。
2.2 元素定位統(tǒng)一入口接觸過 UI 自動化用例設(shè)計的同學會比較清楚,想通過 selenide&selenium 操作一個元素,其中必不可少的就是對元素定位的描述,通俗的講就是要通知接口在當前頁面操作哪個位置上的元素。定位一個元素的方法很多,常用的有 id,name,css,xpath 等,對應不同的定位方法 selenide&selenium 在處理上也給出了不同接口。這從維護角度上來考慮顯然不是最好的。最好的做法就是用例設(shè)計者只管元素定位和操作事件的調(diào)用,而事件實現(xiàn)上走了哪種渠道最好是無感知,無需維護的。對此框架封裝了一個方法供 driver 調(diào)用,主要功能就是解析描述元素的字符串自動判斷是 id、css 還是 xpath。
2.3 失敗測試用例重試網(wǎng)絡(luò)原因等不確定因素會導致測試用例失敗,這種外部因素導致的失敗一般都會認為它是無效的,為了提高測試報告的可信度,增加了失敗用例重試的機制。具體做法是實現(xiàn)一個用例測試結(jié)果的監(jiān)聽器,當監(jiān)聽器監(jiān)聽到一個 fail 的結(jié)果,會觸發(fā)重試,失敗用例最多重試 3 次。
3、元素定位UI自動化用例其實可以分成兩部分,1. 定位元素;2. 調(diào)用接口操作該元素。其中定位一個元素的方法很多,常用的有 id,name,css,xpath。實際設(shè)計中選擇哪種定位方法一般會在維護角度上考慮的會多一些,因為現(xiàn)在的服務器性能配置等都很優(yōu)秀,所以跑一個WEB-UI用例可以不用考慮性能問題。從維護成本上考慮會優(yōu)先選擇 id、name,其次 css,最后用 xpath。
我們并不能保證每一個 web 系統(tǒng)的所有元素都能給你提供一個唯一 id 或者唯一的 name,當然如果能和前端開發(fā)達成合作這就是一件很美好的事情了,一般情況下我們都需要面對沒有 id 和 name 這兩個屬性的情況。這時我們就可以使用 css 樣式,很多時候 css 樣式是能滿足我們的定位需求。當然在這些都不提供給我們的情況下就只能選擇 xpath,使用 xpath 的優(yōu)點 1. 易獲取,主流瀏覽器只要打開“查看”就可以通過 copy 輕松獲取到;2. 頁面上的元素都可以用 xpath 來描述;缺點,不穩(wěn)定,大量使用的話會給用例維護產(chǎn)生很大的負擔。
xpath 一般只要前端在頁面上做一下小調(diào)整用例就必須重新維護,在不得不使用 xpath 的情況下為了減少今后的維護量可對 xpath 做一些優(yōu)化,可以減少 xpath 的路徑長度提高穩(wěn)定性。以下是實踐過程中最長用到的幾種類型:依靠自己的屬性文本定位,如 //input[@value=‘XXXXX’]
包含指示性字符,如 //input[contains(text(),’指示性字符’)]
巧妙使用 descendant,如 //*[@id=‘a(chǎn)pp-container"]/descendant::input
CI集成用例設(shè)計完成之后就可以加入集成建設(shè),讓UI自動化用例在集成環(huán)境中發(fā)揮作用。測試報告展示使用 reportng。jenkins 的插件可以很好的把 report 呈現(xiàn)出來,所以 reportng + jenkins 是一個很不錯的組合。
搭建的步驟:搭建一個 jenkins。
一臺用于跑 UI 自動化用例的服務器。
將服務器配置成 jenkins 的一個節(jié)點。
jenkins 創(chuàng)建 job,job 中需要使用的插件包含 Git、Excute shell、Editable Email Notification、Publish HTML reports。其中 editable email notification,支持郵件提醒,是個很不錯的插件。支持 html report 格式,附件功能。
常見報錯使用 Bee 過程中經(jīng)常會遇到些問題,這里做下總結(jié)方便 debug。
某些頁面不滾動。有時候一屏展示不了所有的元素。理論上 selenide 或者 selenium 在一個頁面中查找一個元素是可以自動執(zhí)行滾屏,但有些時候滾屏會失效,此時就需要在測試用例中實現(xiàn)滾屏查找元素。
解決方法:void scrollToElement(String element,String …elementType)
有些輸入框不能被 input 接口正常操作。實踐過程中在日歷控件中遇到過,元素定位什么的都對,但就是不能正常被操作。
解決方法:void triggerInput(String element,String …elementType),該接口起到一個觸發(fā)的作用,實際操作中遇到類似的情況可以把它當做一種嘗試。
按鈕不能被 click 接口正常操作。button 元素定位完全正確。且在“檢查”窗口中看到的也是 button 屬性。
解決方法:調(diào)用接口 void clickByText(String text)發(fā)現(xiàn) selenide 或者 selenium 的某些接口不能 work 了,此時最大的可能就是瀏覽器升級了。
解決方法:升級瀏覽器驅(qū)動
元素不可見。有一種元素能在頁面上正常展示但對于工具來說它是不可見的,這是因為在一般情況下元素可見需要滿足以下幾個條件:visibility!=hidden ; display!=none; opacity!=0; height、width都大于0;對于 input 標簽,沒有 hidden 屬性。如截圖就是 opacity=0 的實例。
解決方法:調(diào)用接口 void clickByJs(String element,String ... elementType)
結(jié)束語Bee 是在開源工具的基礎(chǔ)上做了些優(yōu)化,目前為止 Bee 更多的是在 driver 層做了些努力,數(shù)據(jù)層、業(yè)務層以及用例層的解決方案還有很大的提升空間。實現(xiàn)一個 WEB-UI 自動化用例主流的方法有錄制和代碼實現(xiàn)這兩種,其實兩種方法各有優(yōu)劣。
Bee 還不完美,后期還需繼續(xù)努力。感謝一直以來支持 Bee 開發(fā)的小伙伴,有你有贊,有你有 Bee。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/8812.html
摘要:在有贊的技術(shù)演進。業(yè)務數(shù)據(jù)量正在不斷增大,這些任務會影響業(yè)務對外服務的承諾。監(jiān)控需要收集上執(zhí)行的的審計信息,包括提交者執(zhí)行的具體,開始結(jié)束時間,執(zhí)行完成狀態(tài)。還有一點是詳細介紹了的原理,實踐中設(shè)置了的比默認的減少了以上的時間。 前言 有贊數(shù)據(jù)平臺從2017年上半年開始,逐步使用 SparkSQL 替代 Hive 執(zhí)行離線任務,目前 SparkSQL 每天的運行作業(yè)數(shù)量5000個,占離線...
摘要:在有贊的技術(shù)演進。業(yè)務數(shù)據(jù)量正在不斷增大,這些任務會影響業(yè)務對外服務的承諾。監(jiān)控需要收集上執(zhí)行的的審計信息,包括提交者執(zhí)行的具體,開始結(jié)束時間,執(zhí)行完成狀態(tài)。還有一點是詳細介紹了的原理,實踐中設(shè)置了的比默認的減少了以上的時間。 前言 有贊數(shù)據(jù)平臺從2017年上半年開始,逐步使用 SparkSQL 替代 Hive 執(zhí)行離線任務,目前 SparkSQL 每天的運行作業(yè)數(shù)量5000個,占離線...
摘要:一背景業(yè)務組件化或者叫模塊化作為移動端應用架構(gòu)的主流方式之一,近年來一直是業(yè)界積極探索和實踐的方向。有贊移動團隊自年起也在不斷嘗試各種組件化方案,在有贊微商城,有贊零售,有贊美業(yè)等多個應用中進行了實踐。相比組件,個人感覺稱之為模塊更為合適。 一、背景 業(yè)務組件化(或者叫模塊化)作為移動端應用架構(gòu)的主流方式之一,近年來一直是業(yè)界積極探索和實踐的方向。有贊移動團隊自16年起也在不斷嘗試各種...
閱讀 2508·2023-04-26 02:47
閱讀 2999·2023-04-26 00:42
閱讀 865·2021-10-12 10:12
閱讀 1372·2021-09-29 09:35
閱讀 1688·2021-09-26 09:55
閱讀 478·2019-08-30 14:00
閱讀 1532·2019-08-29 12:57
閱讀 2350·2019-08-28 18:00