前言
完全自動的業(yè)務測試可以說是自動化測試的終極夢想,不需要任何的自動化代碼京办,就可以實現(xiàn)對業(yè)務邏輯的自動測試,極大的釋放了人力帆焕;但僅稱作是夢想也是有原因的惭婿,形態(tài)各異,日趨復雜的業(yè)務邏輯叶雹,基本讓全自動淪為奢望财饥,即便是加上最新的ai技術(shù),也無法搞定所有的業(yè)務場景折晦;
但是钥星,先退一步,完成半個小目標满着,總歸還是可以的谦炒。
背景
BG主要業(yè)務線的實現(xiàn)載體為web或者h5,各業(yè)務線更新上線頻繁漓滔,實現(xiàn)完全的自動化腳本覆蓋維護成本過高编饺;因此,需要一種工具响驴,可以在低人力成本的前提下透且,通過設立基準線,利用工具同時遍歷基準和新版本的頁面,通過圖像對比的方式秽誊,自動得出差異鲸沮;再加以人工檢視,最快程度的完成新版本回歸工作锅论。
目標
- 低代碼化使用讼溺,可自動遍歷指定網(wǎng)頁
- 頁面覆蓋率40%以上
- 結(jié)果自動進行圖像差異比對
實現(xiàn)過程
測試流程
整體測試流程如下圖(引自圖像對比在UI測試中的實踐-技術(shù)篇)
通過總?cè)肟陂_啟基準和對比網(wǎng)頁的自動遍歷,并在每步驟后截圖最易,當全部遍歷完畢時怒坯,將基準和對比版本的截圖上傳到對比引擎,并最終進行展示藻懒。
關(guān)鍵技術(shù)點
滑塊驗證碼的自動登錄實現(xiàn)
由于BG大部分項目均存在滑動驗證碼才能登錄剔猿,過往的自動化腳本是采用cookies注入規(guī)避該項,但并非所有項目都存在該方式可供使用嬉荆;因此若需大規(guī)模能否自動化過滑塊驗證碼是較為重要的技術(shù)關(guān)鍵點归敬。
本次開發(fā)主要使用了目標檢測模型yolov5,通過不斷爬取驗證碼圖片鄙早,并進行人工標注訓練滑塊位置汪茧,將訓練好的模型通過服務化的方式對外提供接口,最終實現(xiàn)上傳驗證碼圖片后限番,可自動識別缺口位置舱污,再通過自動化技術(shù)進行滑動處理。
需要說明是扳缕,一般而言慌闭,selenium技術(shù)棧中,滑動使用的是win的鍵鼠api躯舔,但實踐下來不建議這里使用驴剔,是因為,為了保證截圖的長度可以截取到全部網(wǎng)頁列表粥庄,因此丧失,使用了無頭瀏覽器的形式啟動web;而該方式無法使用win的鍵鼠api對滑塊進行操作惜互。
實際操作里布讹,這塊使用了js注入實現(xiàn)了滑塊滑動,js代碼如下:
js_str = """
btn=document.getElementsByClassName("geetest_slice_bg")[0];
mousedown = document.createEvent("MouseEvents");
rect = btn.getBoundingClientRect();
x = rect.x||rect.left;
y = rect.y||rect.top;
//點擊滑塊
mousedown.initMouseEvent("mousedown",true,true,window,0,
x, y, x, y,false,false,false,false,0,null);
btn.dispatchEvent(mousedown);
var mousemove = document.createEvent("MouseEvents");
var move_x = {move_x};
mousemove.initMouseEvent("mousemove",true,true,window,0,
x+move_x, y, x+move_x, y,false,false,false,false,0,null);
btn.dispatchEvent(mousemove);
var mouseup = document.createEvent("MouseEvents");
mouseup.initMouseEvent("mouseup",true,true,window,0,x+move_x, y, x+move_x, y,false,false,false,false,0,null);
btn.dispatchEvent(mouseup);""".format(move_x=offset) """
網(wǎng)頁自動遍歷關(guān)鍵技術(shù)實現(xiàn)
js抓取元素xpath
抓取流程
該部分主要流程圖如下:
元素過濾規(guī)則
web頁面上各項元素很多训堆,許多元素的點擊事件都是一層一層往下傳下來的描验,因此,如果不加篩查每個元素都點坑鱼,會造成很多冗余點擊膘流;此外絮缅,業(yè)務上也有很多元素不想進行點擊或者需要更改點擊順序;這里做了幾層過濾規(guī)則呼股。
1耕魄、 手形標志過濾
一般而言,鼠標懸浮到元素上方是手形標志時彭谁,通常代表該元素是設計上可進行交互的吸奴,因此,需要首先過濾掉不具備手形樣式的元素(getComputedStyle(nodes[i]).cursor === 'pointer')缠局。
2则奥、 黑區(qū)域控制
很多時候,業(yè)務上某些區(qū)域下的元素都不想進行點擊(如富文本框甩鳄、不可操作數(shù)據(jù)等)逞度,因此,通過cssname指定元素區(qū)域后妙啃,可過濾掉在該區(qū)域下的所有元素不參與xpath列表生成。
3俊戳、 cssname黑名單
除了區(qū)域控制外揖赴,也提供了基于cssname的黑名單,只要元素樣式包含該css抑胎,則將其過濾燥滑。
4、 targetname黑名單
除了css樣式黑名單外阿逃,還可以指定targetname如style铭拧、script等無法點擊的target類型。
5恃锉、 優(yōu)先級控制
通過指定的cssname進行排序搀菩,凡是在該cssname區(qū)域下的所有元素,優(yōu)先級都會被排到后面破托。
短xpath構(gòu)建
通常而言肪跋,市面上一般使用長xpath,也就是full xpath進行xpath構(gòu)建土砂,這種全路徑的xpath優(yōu)點是可識別性更高州既,很難出現(xiàn)不同頁面相同的xpath;但缺點是路徑過長萝映,不夠穩(wěn)定吴叶,路徑節(jié)點的中的元素只要一個變化,就可能導致認為出現(xiàn)了一個新元素序臂;
因此蚌卤,在通常的長xpath構(gòu)建規(guī)則基礎(chǔ)上,這里加以改良,通過對比全局dom造寝,增加了諸如text磕洪、css、id等特征點的識別诫龙,典型的短xpath類似:
//*[@class='el-icon-switch-button']/parent::*析显、 //*[text()='修改結(jié)果']
主遍歷邏輯
該部分主要流程圖如下:
查丟策略
抓取元素后,其實遍歷策略僅僅是操作進行挨個點擊签赃,遞歸直到元素列表為空而已谷异;重點在于,經(jīng)過點擊操作后锦聊,很可能會進行頁面的跳轉(zhuǎn)歹嘹,或者發(fā)生新元素對舊元素的遮蓋,從而導致原先元素列表內(nèi)的元素無法被點擊到孔庭,也就是丟元素尺上。
這里采用了多種策略,在元素丟失的情況下進行查找圆到,盡量避免丟元素的發(fā)生怎抛。
1、 步驟回溯
在點擊元素時芽淡,每次新產(chǎn)生元素马绝,都會為新產(chǎn)生的元素進行映射表記錄,將點擊了XX元素導致新產(chǎn)生XXX元素列表通過鍵值對的形式記錄下來挣菲;在丟失某個元素時富稻,先查找這個元素對應的映射元素是什么(也就是點擊什么元素導致出現(xiàn)的這個元素),如果當前頁有這個映射元素白胀,就點擊這個映射元素椭赋,再查找這個丟失的元素;如果當前頁沒有這個映射元素纹笼,就去找這個映射元素又是點擊什么元素出現(xiàn)的(也就是這個映射元素的映射元素是什么)纹份,找到后重復以上流程,直到可以按照記錄的步驟將丟失的元素點出來廷痘。
2蔓涧、位置回溯
每次生成新的元素列表后,都會先記錄該元素列表內(nèi)笋额,所有元素的位置信息元暴;一旦元素丟失無法找到,就會嘗試在當前頁查找這個元素的位置上兄猩,有沒有元素茉盏,如果有鉴未,位置信息是否和原元素的位置信息一致,如果一致鸠姨,就代表找到了铜秆。
3、url回溯
很多時候讶迁,點擊元素會跳轉(zhuǎn)到新的url上连茧,在當前頁是不可能找到的;因此巍糯,在生成元素列表時啸驯,還會記錄一份元素和url的映射關(guān)系,當元素丟失時祟峦,如果這個元素的映射url和當前的url不一致罚斗,則會拉回記錄的映射url,再進行元素查找宅楞。
圖片對比引擎mico
在遍歷和截圖生成完畢后针姿,需要上傳一份基準版本和一份對比版本的截圖到圖片對比引擎進行對比;這里直接使用的開源的圖片對比引擎mico厌衙,詳見mico的說明:https://arxman.com/micoo/
最終效果
通過各項黑名單和優(yōu)先級的配置后搓幌,經(jīng)過實際的項目驗證,可到90%的頁面覆蓋率迅箩。