本文章轉(zhuǎn)載于搜狗測(cè)試
在iOS自動(dòng)化測(cè)試中UI Automation的對(duì)象,都是以UIAxxx的形式出現(xiàn)的,例如UIAButton等。UIA是UI Automation的縮寫,如果忽略掉前綴,直接看對(duì)象的名稱,在表達(dá)方面應(yīng)該會(huì)明確。接下來(lái)對(duì)UI Automation所提供的API進(jìn)行初步了解吧。
UIALogger日志輸出
負(fù)責(zé)日志輸出的對(duì)象是UIALogger,主要有兩部分的職責(zé):記錄測(cè)試結(jié)果;負(fù)責(zé)各個(gè)級(jí)別的日志結(jié)果輸出。
在記錄測(cè)試結(jié)果方面,有l(wèi)ogFail()、logPass()方法和logStart()方法。logStart()方法會(huì)在測(cè)試即將開始的時(shí)候調(diào)用,并且在測(cè)試結(jié)束后,和logFail()或logPass()方法配對(duì)出現(xiàn)完成一個(gè)測(cè)試方法的開始部分和最后的完成部分的結(jié)果記錄,logPass()和logFail()是一對(duì)函數(shù),分別表示方法測(cè)試通過和未通過。
在日志輸出方面,一般常用的事logMessage()方法,日志輸出是我們調(diào)試UI Automation腳本唯一的手段,在編寫自動(dòng)化測(cè)試腳本的時(shí)候,一定要掌握l(shuí)ogMessage()方法。需要注意的是logMessage()只接受字符串類型的參數(shù)。例如:UIALogger.logMessage(“JUST TEST”)就是一個(gè)有效地輸出,但是如果這樣的:UIALogger.logMessage(123);就不會(huì)有任何輸出,這里需要強(qiáng)制的是把數(shù)字類型轉(zhuǎn)化為字符串類型就可以有內(nèi)容輸出了。
手勢(shì)動(dòng)作的模擬
UI Automation的API給用戶提供了很多手勢(shì)操作的模擬方式,現(xiàn)在介紹幾種常用的手勢(shì)動(dòng)作模擬方式,為大家提供一個(gè)思路。如果希望更加全面的學(xué)習(xí),建議參考Apple官方文檔。
模擬操作動(dòng)作的方法主要由兩個(gè)主類提供,在API調(diào)用方式上也有一些其別,所以這里再次細(xì)分了兩種方式,分別為UIAElement方式和UIATarget方式。
1. UIAElement方式
(1)點(diǎn)擊
tap()方法,一個(gè)button或者一個(gè)表單的某一行(UIATableViewCell)都可以使用tap方法操作。但如果是一個(gè)閱讀器的話,本身被操作的控件區(qū)域很大,在控件內(nèi)部還會(huì)細(xì)分操作區(qū)域。不同區(qū)域的相同操作可能效果不同。在這樣的測(cè)試需求前面,只使用tap()方法明顯是不能滿足需求的。這時(shí)需要使用更高級(jí)的操作方式tapWithOptions(option)。例如,UIAElement.tap
WithOptions({x:0.9,y:0.5})。
如果題詞點(diǎn)擊不能滿足需求,還可以使用doubleTap()方法來(lái)模擬雙擊的操作。如果單指的點(diǎn)擊不能滿足需求,可以使用twoFinger
Tap()來(lái)模擬雙指的點(diǎn)擊操作。
(2)滑動(dòng)或拖拽
滑動(dòng)和拖拽在UI Automation中區(qū)別不大,唯一區(qū)別在于操作時(shí)的延時(shí)時(shí)間不同。現(xiàn)在可以從接口層面來(lái)查看滑動(dòng)操作和拖拽操作的區(qū)別。
滑動(dòng)實(shí)例:
UIAElement.flickInSideWithOption({touchCount:2,startOffset:{x:0.5,y:0.9}, endOffset:{x:1.0, y:0.9}});
拖拽實(shí)例:
UIAElement.dragInsideWithOptions({touchCount:2,startOffset:{x:0.5,y:0.9}, endOffset:{x:1.0, y:0.9}, duration:1});
從上面兩個(gè)實(shí)例中可以看出,拖拽比滑動(dòng)函數(shù)多了一個(gè)duration參數(shù),這個(gè)duration表示操作時(shí)手指和屏幕的接觸時(shí)間,duration參數(shù)一般只接收值為0或1的傳入(你可能還會(huì)看到有些文檔里賣弄傳入2或者3,但官方文檔中未對(duì)這些參數(shù)進(jìn)行詳細(xì)說(shuō)明,而且從實(shí)際操作的角度來(lái)看好像也沒有看出具體的差別),0代表flick方式接觸時(shí)間,1代表drag和pinch等操作的將誒出時(shí)間。還需要特別說(shuō)明,duration參數(shù)有一個(gè)默認(rèn)值并且為0.也就是說(shuō)dragInsideWithOptions方法如果沒有顯示傳入duration的值,dragInsideWithOptions和flickInsideWithOptions是等價(jià)的。這兩個(gè)方法都有一個(gè)參數(shù)為touchCount,這個(gè)參數(shù)表示滑動(dòng)或拖拽操作的手指?jìng)€(gè)數(shù),默認(rèn)為1。單指滑動(dòng)或拖拽就可以不用設(shè)置這個(gè)參數(shù)了。
2. UIATarget方式
(1)點(diǎn)擊
在點(diǎn)擊方面,UIATarget和UIAElement的方式一樣提供了兩種方法供開發(fā)者使用,即tap()和tapWithOptions()方法。唯一不同的是傳入的參數(shù)。Target的實(shí)例:
UIATarget.localTarget.tap({x:300,y:200});
UIATarget.localTarget.tapWithOptions({x:300,y:200}, {tapCount:1,touchCount:2,duration:1});
在tap方法里面需要傳入點(diǎn)擊的具體坐標(biāo),因?yàn)門arget是一個(gè)全局對(duì)象,操作區(qū)域非常大,需要明確指定點(diǎn)擊的區(qū)域。在tapWithOptions方法中,還需要傳入點(diǎn)擊的次數(shù)(tapCount,默認(rèn)值為1),點(diǎn)擊時(shí)手指的個(gè)數(shù)(touchCount,默認(rèn)值為1),點(diǎn)擊時(shí)手指接觸時(shí)間(duration,默認(rèn)值為0)。
同樣,UIATarget方式也有doubleTap方法和twoFingerTap方法。
(2) 滑動(dòng)和拖拽
在UIATarget方式中,滑動(dòng)的方法為:flickFromTo;拖拽的方法為:fragFromToForDuration。雖然方法名字有所變化,但是用法和UIAElement方式完全相同,我們直接給出實(shí)際的例子:
UIATarget.localTarget().flickFromTo({x:160,y:200},{x:160,y:400})
UIATarget.localTarget().dragFromToDuration({x:160,y:200},{x:160,y:200}, 1);
在Target方式中,還有一種操作,非常類似于滑動(dòng)和拖拽,在官方文檔中稱為pinch(一般可以翻譯為捏合或縮放,但都不是很準(zhǔn)確),一般pinch最常用的操作是,在瀏覽照片時(shí)可以通過pinch對(duì)照片進(jìn)行縮放。pinch根據(jù)移動(dòng)的方式不同而被劃分為兩種:pinchOpen和pinchClose。實(shí)例如下:
UIATarget.localTarget().pinchOpenFromToForDuration({x:20,y:200}, {x:300,y:200}, 1);
UIATarget.localTarget().pinchCloseFromToForDuration({x:20,y:200}, {x:300,y:200}, 1);
延時(shí)處理
在延時(shí)處理方面,有delay()方法,在腳本中使用起來(lái)非常簡(jiǎn)單、方便。在延時(shí)處理時(shí),還有更加高級(jí)的方法需要介紹一下。
在遍歷控件樹時(shí),一般會(huì)采用這樣的方式遍歷控件樹:
var elementArray = UIAElement.elements();
正常情況下,這段代碼很快就會(huì)返回一個(gè)UIAElementArray對(duì)象,并傳遞給變量,但是當(dāng)這個(gè)UIAElement沒有子元素時(shí),這個(gè)語(yǔ)句就會(huì)執(zhí)行的非常慢,因?yàn)闆]有子元素了,UI Automation是通過超時(shí)機(jī)制來(lái)處理這個(gè)異常的。在沒有任何設(shè)置的情況下,UI Automation默認(rèn)的超時(shí)時(shí)間為5秒。頻繁地遇到這種情況會(huì)使測(cè)試腳本的執(zhí)行速度拖延,過慢的測(cè)試腳本運(yùn)行會(huì)大幅度降低測(cè)試腳本的可用性。這時(shí)需要把超時(shí)時(shí)間設(shè)置的短一些。例如:
UIATarget.localTarget().setTimeout(1);
這樣就把超時(shí)時(shí)間設(shè)置為1秒,從而提升了腳本的執(zhí)行速度。但是使用setTimeout方法會(huì)有一個(gè)隱患,因?yàn)檫@種方式的設(shè)置是全局的一種方式,UIATarget.localTarget().setTimeout(1)會(huì)使得這個(gè)測(cè)試運(yùn)行過程中超時(shí)時(shí)間都被強(qiáng)制改為1秒,或許在有些函數(shù)方法內(nèi)部還需要超時(shí)時(shí)間為5秒。所以需要有一種更加優(yōu)雅的方式來(lái)解決這個(gè)問題。UI Automation提供了這樣的方式,實(shí)例代碼如下:
UIATarget.localTarget().pushTimeout(1);
var elementArray = UIAElement.elements();
UIATarget.localTarget().popTimeout(1);
pushTimeout和popTimeout成對(duì)出現(xiàn),在這兩個(gè)方法中間的代碼會(huì)被修改超時(shí)時(shí)間,不在這對(duì)語(yǔ)句中間出現(xiàn)的代碼,不會(huì)受到任何影響。