日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

android app自动化测试之UIAutomator

發(fā)布時(shí)間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android app自动化测试之UIAutomator 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、UIAutomator

???????? Android自動(dòng)化測(cè)試工具有很多,但是要免費(fèi)、易上手,本人覺得就直接使用Eclipse自帶的UIAutomator就不錯(cuò)。測(cè)試人員無(wú)需跟開發(fā)要代碼信息,只要手機(jī)上有安裝之后的APP自己就能做出自動(dòng)測(cè)試用例,況且一通百通,就算是不滿足于UI測(cè)試的,找個(gè)簡(jiǎn)單易上手的先明白原理,再深入了解其它復(fù)雜工具也會(huì)輕松很多。何樂而不為呢?

UIAutomator是Eclipse自帶的用于UI自動(dòng)化測(cè)試工具,可仿真APP上的單擊、滑動(dòng)、輸入文本等操作。

???????? 在使用之前,需要安裝好java有關(guān)的JDK,SDK,然后配置java環(huán)境變量。關(guān)于安裝JDK,SDK,配置JAVA環(huán)境變量網(wǎng)上有數(shù)不清的教程,這里就不廢話了。直接進(jìn)入主題。

???????? 還是簡(jiǎn)單介紹一下自動(dòng)化測(cè)試代碼中使用到的類關(guān)系:現(xiàn)在還不清楚也沒有關(guān)系,先讓程序跑起來(lái),然后在使用API的過(guò)程中自然就理解了。

?

1、創(chuàng)建java工程

???????? 打開Eclipse,操作步驟: 點(diǎn)擊“File—>New—>java Project”,然后打開如下圖的界面:

?

其它的先不用管,既然要求必須輸入Project name,那就輸入。請(qǐng)用英文命名,很多時(shí)候中文會(huì)帶來(lái)許多意想不到的問(wèn)題。

輸入Project name之后,點(diǎn)擊“Next”進(jìn)入下一步,看到的界面如下:

?

Source下的東西無(wú)需關(guān)注,點(diǎn)擊“Libraries”,既然是調(diào)用java自帶的UIAutomator,就要先引入U(xiǎn)IAutomator使用到的包。導(dǎo)入uiautomator相關(guān)包:點(diǎn)擊“Add External JARs”

???????? 先要找到自己的android.jar 和 Uiautomator.jar 包的位置,一般在安裝文件下的adt-bundle-windows-x86-20130917\sdk\platforms\android-18\ 下,具體要找到自己電腦上的jar位置哦,

?

選中兩個(gè)jar文件,“打開”導(dǎo)入。

此外還需要再加入本地庫(kù),點(diǎn)擊“Add Library”,選擇Junit,后點(diǎn)擊“next”,使用默認(rèn)的JUit3。點(diǎn)擊“Finish”。

?

回到New Java Project,點(diǎn)擊“Finish”即可創(chuàng)建工程成功。

?

2、創(chuàng)建class文件

???????? 剛剛創(chuàng)建的工程,Src下還沒有任何東西,我們需要?jiǎng)?chuàng)建一個(gè)Class文件,用來(lái)寫自動(dòng)化程序代碼。

創(chuàng)建class文件:項(xiàng)目名稱右鍵——NEW——class,寫class內(nèi)容如下

?

???????? 2.1 import UIautomator兩個(gè)包

???????? 2.2 class 名稱必須和XXX.java名稱相同

???????? 2.3每一個(gè)public開頭,且以test命名開始的函數(shù),系統(tǒng)就視為一個(gè)case,運(yùn)行時(shí)方法的調(diào)用順序并不是代碼中的位置順序,而是根據(jù)方法名的ASCII碼大小順序調(diào)用的。

???????? 2.4每一個(gè)class都必須繼承自UiAutoMatorTestCase

3、生成xml 文件

?

?

找到target版本:>android list targets

Id:1

創(chuàng)建build.xml到測(cè)試工程中去,用于生成.jar文件:>Android create UItest-project –n testprojectname –t 1 –p testprojectpath

?

4.build jar 文件

???????? 4.1 Update Ant to 1.9

???????? 4.2 配置ant使用的javac版本:

?????????????????? 右鍵build.xml—》RUN AS —》 External Tools Configurations。

??????? main Tab 下輸入Argumens: -Dbuild.compiler=javac1.7——》

?????????????????? Apply。

?

?????????????????? 4.3配置sdk中的build.xml 文件E:\Android\android\adt-bundle-windows-x86-20130917\sdk\tools\ant\build.xml: 找到j(luò)avac,添加includeantruntime="false"

<javac encoding="${java.encoding}"

??????????????????? source="${java.source}" target="${java.target}"

??????????????????? debug="true" extdirs="" includeantruntime="false"

??????????????????? destdir="${out.classes.absolute.dir}"

??????????????????? bootclasspathref="project.target.class.path"

??????????????????? verbose="${verbose}"

??????????????????? classpathref="project.javac.classpath"

??????????????????? fork="${need.javac.fork}" includeantruntime="false">

??????????????? <src path="${source.absolute.dir}" />

??????????????? <src path="${gen.absolute.dir}" />

??????????????? <compilerarg line="${java.compilerargs}" />

??????????? </javac>

5. push jar文件到手機(jī)

Cmd環(huán)境下需要先找到adb.exe所在位置目錄,完整的命令語(yǔ)句:

adb push <path_to_output_jar> ?/data/local/tmp

“<path_to_output_jar>”即要放到手機(jī)里的jar文件名及路徑

?

相反的如果是從手機(jī)復(fù)制文件到電腦:

6. 運(yùn)行測(cè)試

Cmd環(huán)境下需要先找到adb.exe所在位置目錄,完整的命令語(yǔ)句:

adb shell uiautomator runtest? XXX.jar ?-c ?XXXClassname

備注:XXX.jar需要運(yùn)行的jar文件名,

?????? Classname: 需要運(yùn)行jar中的哪個(gè)類的名字

?

?

7.測(cè)試結(jié)果

運(yùn)行結(jié)果如下:

?

Current: 當(dāng)前運(yùn)行的測(cè)試編號(hào),與方法名稱相關(guān)

Class:當(dāng)前運(yùn)行的函數(shù)所在的類

Numtests:測(cè)試的總數(shù),每一個(gè)public testXX就是一個(gè)測(cè)試數(shù)

Test: 當(dāng)前測(cè)試的函數(shù)名稱

INSTRUMENTAION_STATUS_CODE:測(cè)試狀態(tài)碼,1表示正在執(zhí)行,0表示執(zhí)行成功,-1編輯運(yùn)行錯(cuò)誤

二、使用UIAUTOMATORVIEWER獲取APP控件

1.手機(jī)打開app

使用UIAutomator獲取手機(jī)app控件時(shí),先在手機(jī)上運(yùn)行起對(duì)應(yīng)app

2 .電腦連接手機(jī)

???????? 確保電腦與手機(jī)已連通。

???????? 先在cmd界面到達(dá)java的adb.exe所在位置,

???????? 運(yùn)行命令“ >adb shell ”獲取當(dāng)前連接電腦的設(shè)備,如下圖,如果adb shell 運(yùn)行正常,會(huì)彈出“shell@hwH30-C00:/$”

?????? 有多個(gè)設(shè)備連接開發(fā)機(jī)器時(shí)(模擬器或真機(jī)),通過(guò)設(shè)置ANDROID_SERIAL環(huán)境變量指定需要截圖的設(shè)備。比如下圖的:shell@hwH30-C00:/$ set ANDROID_SERIAL= hwH30-C00,設(shè)置連接成功后,返回:“set ANDROID_SERIAL=hwH30-C00”

?????? adb devices命令查看連接中的設(shè)備編號(hào)

?

如果當(dāng)前只連接了一個(gè)設(shè)備,則不用再在Cmd中執(zhí)行連接命令

3.運(yùn)行uiautomatorviewer.bat

找到uiautomatorviewer.bat安裝目錄,本機(jī)中的位置如下:

E:\Android\android\adt-bundle-windows-x86-20130917\sdk\tools\uiautomatorviewer.bat

雙擊運(yùn)行uiautomatorviewer.bat,打開界面如下圖:

?

???????? 上圖中左半部分顯示當(dāng)前手機(jī)的呈現(xiàn)界面,若要獲取其它界面的控件,需要在手機(jī)上后,點(diǎn)擊上圖左上角頂部的刷新,重新獲取新界面。

???????? 上圖右半部分顯示當(dāng)前界面的所有ui元素層即控件信息。右上半部分顯示層級(jí),右下部分顯示指定層級(jí)上具體的控件屬性,比如當(dāng)前屬性“class”:當(dāng)前控件的所在class

“Package”:顯示當(dāng)前控制所在包

“Resource-id”:這個(gè)屬性有最好了,有些Android開發(fā)人員沒有為每個(gè)控件單獨(dú)命名,在抓取的時(shí)候就非常不方便。如果有Resource-id,在抓取控件時(shí),直接用Resource-id就能獲取到正確的控件,并且操作正確,如果沒有Resource-id,就只能通過(guò)查找同類控件后再按順序獲取了。比如先找到所有的textbox控件,再?gòu)乃械膖extbox控件中按序取幾個(gè),才能抓取到對(duì)應(yīng)控件。

還有一些控件屬性顯示是否可見,是否checked,有實(shí)際應(yīng)用需要時(shí),可以獲取

這里附上一個(gè)簡(jiǎn)單的測(cè)試java源代碼,供參考代碼格式

import com.android.uiautomator.core.UiDevice;

import com.android.uiautomator.core.UiObject;

import com.android.uiautomator.core.UiObjectNotFoundException;

import com.android.uiautomator.core.UiScrollable;

import com.android.uiautomator.core.UiSelector;

import com.android.uiautomator.testrunner.UiAutomatorTestCase;

?

public class MyTestCase extends UiAutomatorTestCase {

??? public void testDemo() throws UiObjectNotFoundException {

?????????? //點(diǎn)擊home回到桌面

?????? UiDevice device = getUiDevice();

?????? device.pressHome();

?????????? // 點(diǎn)擊并等待打開app

?????? UiObject czmApp = new UiObject(new UiSelector().className(android.widget.TextView.class.getName()));?????

??? ??? czmApp.clickAndWaitForNewWindow();?

??? ??? sleep(1000);

??? ??? //登錄;instan從0開始,

??? ??? UiObject username= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/login_username_edit"));??

??? ??? username.clearTextField();

??? ??? username.setText("15300000018");

??? ??? UiObject pwd= new UiObject(new UiSelector().className("android.widget.EditText").enabled(true).resourceId("com.wlyc.warehousechampions:id/login_password_edit"));

??? ??? pwd.clearTextField();

??? ??? pwd.setText("00OA8C");

??? ??? device.pressBack();

?????? sleep(500);

??? ??? UiObject enter= new UiObject(new UiSelector().className("android.widget.Button").resourceId("com.wlyc.warehousechampions:id/login_btn"));

??? ??? enter.click();

??? ??? sleep(5000);

??? ??????? ????

??? ??? //跳轉(zhuǎn)到“我的”

??? ??? UiObject My= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/personcenter"));??

??? ??? My.clickAndWaitForNewWindow();

??? ??? sleep(500);

??? ??? //檢查認(rèn)證狀態(tài)

??? ??? UiObject result= new UiObject(new UiSelector().className("android.widget.TextView").resourceId("com.wlyc.warehousechampions:id/personcenter_apply_status"));??

??? ??? int n=result.getText().length();

??? ??? //認(rèn)證審核中

??? ??? n=Dur_verify(n);?

??? ??? //認(rèn)證失敗 或者認(rèn)證成功

??? ??? if(n==4)

??? ??? {

??? ??? UiObject failed= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/apply_certificate_layout"));??

??? ??? failed.click();

??? ??? UiObject isedit= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/titlebar_right_layout"));??

?????? ??? //認(rèn)證失敗

??? ??? if(isedit.exists())

??? ??? {

?????? ??? isedit.click();

?????? ??? write();

?????? ??? sleep(500); ?

?????? ??? }

??? ??? else //認(rèn)證成功

??? ??? {??

??? ??? ??? UiObject backtoMy= new UiObject(new UiSelector().className("android.widget.LinearLayout").resourceId("com.wlyc.warehousechampions:id/titlebar_left_layout"));

??? ??? ??? backtoMy.click();

??? ??? ??? Release();

?????? ??? }

?????? ?}

??? ??? n=result.getText().length();

??? ??? n=Dur_verify(n);

??? ??? Release();

??? ??? }

????????????? //錄入并提交企業(yè)認(rèn)證

??? public void write()throws UiObjectNotFoundException

??? ??? {

??? ??? ??? //跳轉(zhuǎn)到企業(yè)認(rèn)證

??? ??? UiObject Company= new UiObject(new UiSelector().className("android.widget.RadioButton").resourceId("com.wlyc.warehousechampions:id/company_certificate"));??

?????? ??? Company.click();

?????? ??? //錄入企業(yè)認(rèn)證信息

?????? ??? UiObject CompanyName=new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/cettificate_companyname_edit"));

?????? ??? CompanyName.setText("test");

?????? ??? sleep(500);

?????? ??? //拍照

?????? ??? UiObject photo= new UiObject(new UiSelector().className("android.widget.ImageView").resourceId("com.wlyc.warehousechampions:id/uploadimage_image"));??

?????? ??? photo.click();

?????? ??? sleep(500);

?????? ??? UiObject takephoto= new UiObject(new UiSelector().className("android.widget.TextView").instance(1));??

?????? ??? takephoto.click();

?????? ??? sleep(500);

?????? ??? UiObject phototake= new UiObject(new UiSelector().className("android.widget.ImageView").resourceId("com.android.gallery3d:id/shutter_button"));??

?????? ??? phototake.click();

?????? ??? sleep(500);

?????? ??? UiObject photook= new UiObject(new UiSelector().className("android.widget.ImageView").resourceId("com.android.gallery3d:id/btn_done"));??

?????? ??? photook.click();

?????? ??? sleep(500);

?????? ??? //提交認(rèn)證

?????? ??? UiObject commit= new UiObject(new UiSelector().className("android.widget.Button").resourceId("com.wlyc.warehousechampions:id/commit_btn"));??

?????? ??? commit.click();

?????? ??? sleep(500);???

??? ??? }

????????????? //發(fā)布倉(cāng)庫(kù)

??? ??? public void Release() throws UiObjectNotFoundException

??? ??? {

??? ??? UiObject wh_release= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/warehouse_distribute"));??

??? ??? wh_release.click();

??? ? ?? UiObject wh_name= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/warehouse_name_edit"));??

??? ??? wh_name.setText("nametest");

??? ??? UiObject wh_ctg= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/spinnerview_layout"));??

??? ??? wh_ctg.clickAndWaitForNewWindow();

??? ??? UiObject wh_ctg1= new UiObject(new UiSelector().className("android.widget.TextView").resourceId("com.wlyc.warehousechampions:id/spinnerview_listitem_text"));

??? ? ? ????wh_ctg1.click();

??? ? ????? UiObject wh_mod= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/spinnerview_layout").instance(1));??

??? ??? wh_mod.click();

??? ??? sleep(500);

??? ??? UiObject wh_mod1= new UiObject(new UiSelector().className("android.widget.TextView").enabled(true).instance(0));??

??? ??? wh_mod1.click();

??? ???

??? ??? sleep(500);

??? ? ? ????UiObject wh_area= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/warehouse_area_edit"));??

??? ??? wh_area.setText("5000");

??? ??? UiObject wh_area_low= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/warehouse_rentarea_edit"));??

??? ??? wh_area_low.setText("500");

??? ??? UiObject wh_area_cpb= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/warehouse_availrentarea_edit"));??

??? ??? wh_area_cpb.setText("1000");

??? ??? UiObject wh_pric= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/warehouse_price_edit"));??

??? ??? wh_pric.setText("26");

??? ??? UiObject wh_etpris= new UiObject(new UiSelector().className("android.widget.EditText").resourceId("com.wlyc.warehousechampions:id/warehouse_company_edit"));??

??? ??? wh_etpris.setText("companyname");

??? ??? UiObject wh_floor= new UiObject(new UiSelector().className("android.widget.CheckBox").enabled(true).instance(0));??

??? ??? wh_floor.click();

??? ??? sleep(500);

??? ??? ??????? //向下滑動(dòng)屏幕

??? ??? UiScrollable? wh_scroll=new UiScrollable(new UiSelector().className("com.wlyc.warehousechampions:id/pulltorefresh_listview"));

??? ? ? ????wh_scroll.setAsVerticalList();

?????????? ;

??? ??? UiObject wh_addre= new UiObject(new UiSelector().className("android.widget.TextView").resourceId("com.wlyc.warehousechampions:id/warehousedetail_hightemperature_unit"));

??? ? ? ????wh_addre.click();

??? ? ? ????

??? ??? }

??? ??? ??? //認(rèn)證審核中等待

??? ??? public int Dur_verify(int n) throws UiObjectNotFoundException

??? ??? {

??? ??? ?while (n!=4) {

??? ??? ??? UiObject My= new UiObject(new UiSelector().className("android.widget.RelativeLayout").resourceId("com.wlyc.warehousechampions:id/personcenter"));

??? ??? ??? My.clickAndWaitForNewWindow();

??? ?????? ??? sleep(5000);

??? ?????? ??? UiObject result= new UiObject(new UiSelector().className("android.widget.TextView").resourceId("com.wlyc.warehousechampions:id/personcenter_apply_status"));

??? ?????? ??? n=result.getText().length();

??? ?????? }

??? ??? ?return n;

??? ??? }

???

}

三、Uiautomator Api分析

???????? UiAutomator主要涉及以下幾個(gè)類,大多數(shù)位于源碼包的com.android.uiautomator.core下,其中粗體字部分為主要會(huì)接觸到的類,熟知這5個(gè)類的作用,就可以大體順暢的寫出UiAutomator的測(cè)試用例。

UiAutomatorTestCase

UiDevice

UiSelector

UiScrollable

UiObject

UiCollection

UiTestAutomationBridge, UiAutomatorBridge

InteractionController, QueryController

UiWatcher

?????????????????? 1、UiAutomatorTestCase

TestCase (Junit) -> UiAutomatorTestCase? -> App Test

???????? 每個(gè)測(cè)試用例(類)都需要繼承UiAutomatorTestCase,以實(shí)現(xiàn)測(cè)試環(huán)境的setup,teardown(拆卸)等同能。而UiAutomatorTestCase則是通過(guò)繼承Junit3中的TestCase類,并在其中的setUp() 、tearDown() 、getParams() 函數(shù)中。其中主要是用Bundle實(shí)現(xiàn)Android Activity之間的通訊。在UiAutomatorTestCase,還加入了getUiDevice()等關(guān)于UiDevice的 函數(shù),以實(shí)現(xiàn)在測(cè)試的任意地方均可調(diào)用UiDevice()。

???? 2UiDevice

???????? 此類主要包含了獲取設(shè)備狀態(tài)信息,和模擬用戶至于設(shè)備的操作兩類api。

可以通過(guò)getDisplaySizeDp(), getDisplayWidth() , getDisplayHeight() ,getProductName() ,getCurrentActivityName(), getCurrentPackageName() 等獲取設(shè)備相關(guān)信息。

pressMenu(), pressBack(), pressHome(), pressSearch() ,pressDPadCenter(), pressDPadRight(), pressDPadLeft(), pressDPadUp(), pressDPadDown() ,pressDelete(), pressEnter(), pressKeyCode(), pressRecentApps(),click(),swipe(),getDisplayRotation() setOrientationLeft()… wakeUp(), sleep() ,dumpWindowHierarchy(), waitForWindowUpdate()等API可以靈活的操縱設(shè)備。

而takeScreenshot() 允許隨時(shí)對(duì)設(shè)備截屏。

???? 3UiSelector

???????? 主要是通過(guò)一定查詢方式,定位到所要操作的UI元素。

???????? 一般UI元素均可通過(guò)以下API定位:text(), textMatches(String regex), textStartsWith(), textContains() ,className() ,classNameMatches(String regex), className(Class type) ,Description(), descriptionMatches(String regex),descriptionStartsWith(),descriptionContains() ,packageName(), packageNameMatches(String regex)。

值得注意的是index()和 instance() 兩個(gè)函數(shù),其中index()是當(dāng)前頁(yè)面的ID編號(hào),instance()則表示在一定的搜索結(jié)果下,獲取的子元素集的第幾個(gè)元素。如:

new UiSelector().className("android.widget.ImageView").enabled(true).instance(2);

???????? 另有enabled(), focused(), focusable(), scrollable(), selected(), checked(), clickable() ,longClickable() ,childSelector()等檢索條件,顧名思義。

???? 4UiObject

???????? UiObject可代表頁(yè)面的任意元素,它的各種屬性定位通常通過(guò)UiSelector來(lái)完成。

???????? 比較常用的Api如clickAndWaitForNewWindow(),表示點(diǎn)擊該元素,并且等待新窗口的展示完畢。這一過(guò)程是Android UI Testing框架支持的,不需要額外的控制等待時(shí)間。

???????? UiObject允許點(diǎn)擊該元素的具體一個(gè)部分,Api如clickTopLeft(), longClickBottomRight(),…

???????? 通過(guò)getText(), getContentDescription(), getVisibleBounds(),… 等api可獲取UiObject的相關(guān)屬性,getPackageName() 可用來(lái)明確是否打開了目標(biāo)測(cè)試的App.

???????? setText(), clearTextField() 可以 用來(lái)設(shè)置以及清空所關(guān)聯(lián)的輸入框。

???????? waitForExists() 可以用來(lái)操縱相關(guān)等待或驗(yàn)證。

???? 5UiCollection

???????? UiCollection一般與UiSelector連用,如它的構(gòu)造函數(shù)也要求提供Uiselector: UiCollection(UiSelector selector)。

它的api較少,主要用以從Uiselector篩選出的元素集中挑出所要的元素:getChildByDescription(), getChildByInstance(), getChildByText() ,以及統(tǒng)計(jì)元素集的個(gè)數(shù)getChildCount()

???? 6UiScrollable

UiObject -> UiCollection ->UiScrollable

???????? UiScrollable 用來(lái)表示可以滑動(dòng)的界面元素,其繼承關(guān)系如上圖所示。

其Api中,setAsVerticalList(), setAsHorizontalList() 用以設(shè)置Ui元素列表是基于橫向滾動(dòng)還是縱向滾動(dòng)。其后可以用getMaxSearchSwipes() ,flingForward(), flingBackward() ,scrollForward(),scrollBackward() ,scrollToEnd(), scrollToBeginning() 等函數(shù)控制滑動(dòng),以及getChildByDescription(), getChildByInstance(), getChildByText() ,scrollIntoView(), scrollTextIntoView(),… 來(lái)選擇是否已經(jīng)轉(zhuǎn)換到具有目標(biāo)元素的頁(yè)面。如:

UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true));

appViews.setAsHorizontalList();

UiObject helperApp;

helperApp = appViews.getChildByText(new UiSelector()

.className(android.widget.TextView.class.getName()), " 91助手 ");? 則若當(dāng)前頁(yè)面沒有91助手APP, 測(cè)試會(huì)自動(dòng)滑動(dòng)頁(yè)面,直到91助手App出現(xiàn)。

???????? 下面介紹下UI Testing Framework構(gòu)成的重要類:

7UiTestAutomationBridge

???????? 這是整個(gè)Testing Framework的基礎(chǔ),此類負(fù)責(zé)連接系統(tǒng)了,記錄最新的可鏈接事件(AccessibilityEvent) , 窗口內(nèi)容查詢Api等。可以被Android App調(diào)用,或者Java程序從shell調(diào)用。

這里需要注意兩個(gè)概念:

???????? 7.1、AccessibilityEvent:所有的Ui元素可以被操縱,因?yàn)檫@些Event都是AccessibilityEvent。對(duì)于怎樣令頁(yè)面元素可以被操縱,使得相關(guān)的事件都是AccessibilityEvent,請(qǐng)參見Uiautomator 詞條-"確認(rèn)程序可以被測(cè)試" 部分。

???????? 7.2、AccessibilityNodeInfo:視窗中的組件樹節(jié)點(diǎn),也就是uiautomtorViewer中展示的各個(gè)節(jié)點(diǎn)。

???????? Api中connect(), disconnect() 負(fù)責(zé)建立與設(shè)備的實(shí)際連接。

executeCommandAndWaitForAccessibilityEvent() performAccessibilityAction() findAccessibilityNodeInfosByText(), findAccessibilityNodeInfoByViewIdInActiveWindow() 都是其中重要的Api。

???? 8UiAutomatorBridge

???????? UiAutomatorBridge是UiTestAutomationBridge的子類,區(qū)別主要是在構(gòu)造函數(shù)中加上了InteractionController 和QueryController 兩大對(duì)象的調(diào)用。以及一些常量定義等。除了上述差異,UiAutomatorBridge還定義了executeCommandAndWaitForAccessibilityEvent() 、onAccessibilityEvent() 、waitForIdle() 、addAccessibilityEventListener() 等函數(shù)。

???? 9InteractionController

???????? 介紹InteractionController,需要先提InteractionProvider,它負(fù)責(zé)注入用戶事件(如點(diǎn)擊、輸入等) ,并且反應(yīng)事件的對(duì)應(yīng)坐標(biāo)。

???????? InteractionController則定義了幾乎所有至于手機(jī)的基礎(chǔ)操作,如runAndWaitForEvents(), clickAndWaitForEvents() ,click(), longTap(), scrollSwipe(),Swipe() ,clickAndWaitForNewWindow() ,touchUp(), touchDown(), TouchMove() ,isNaturalRotation(), setRotationRight(), setRotationLeft() ,freezeRotation() ,wakeDevice(), sleepDevice() 等。

???? 10QueryController

???????? QueryController負(fù)責(zé)把UiSelector 的查找信息轉(zhuǎn)化為AccessibilityNodeInfo。

具體Api如下:findNodePatternRecursive(), translatePatternSelector(), translateReqularSelector(), translateCompoundSelector(), getRootNode() ,findAccessibilityNodeInfo()。

???? 11UiWatcher

???????? UiWatcher只在UiSelector無(wú)法找到匹配的結(jié)果時(shí)被調(diào)用,意在重試、等待頁(yè)面更新 (如彈出對(duì)話框)等。其中只有一個(gè)主要函數(shù):checkForCondition() 。

它的相關(guān)函數(shù)均在UiDevice中,如:UiDevice.registerWatcher() ,UiDevice. resetWatcherTriggers() ,UiDevice.runWatchers() ,UiDevice.removeWatcher()

?

轉(zhuǎn)載于:https://www.cnblogs.com/wangchaozhi/p/5158575.html

總結(jié)

以上是生活随笔為你收集整理的android app自动化测试之UIAutomator的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 中文字幕 欧美激情 | 男生c女生 | a级片中文字幕 | 毛片网站在线播放 | 美女脱裤子打屁股 | 久久露脸国语精品国产91 | 国产欧美另类 | 激情开心网站 | 成人在线观看免费视频 | 国产按摩一区二区三区 | 国产男女猛烈无遮挡a片漫画 | 在线观看免费av片 | 国产午夜精品一区二区三区嫩草 | 日本激情视频在线 | 国产区在线观看视频 | 免费久久久久久 | 欧美在线视频第一页 | 国产视频在线看 | 色射射| 精品看片 | 亚洲第一偷拍 | 欧美黑人一级爽快片淫片高清 | 亚洲国产乱| www.夜夜骑| 91在线视频在线观看 | 相亲对象是问题学生动漫免费观看 | 日韩在线网 | 奴色虐av一区二区三区 | 国产精品老熟女视频一区二区 | 理论毛片 | 天天爱天天做 | exo妈妈mv在线播放高清免费 | 亚洲性夜 | 日本一区二区成人 | 欧洲人妻丰满av无码久久不卡 | 国模视频一区二区 | 女生扒开腿让男生操 | 久久久亚洲av波多野结衣 | 婷婷二区| 黄色不卡 | 日韩中文字幕一区二区三区四区 | 69av网站| 激情视频一区二区 | 国产视频第二页 | 亚洲aaaa级特黄毛片 | 久久精品国产成人av | 精品国产乱码久久久人妻 | 日韩一区二区三区中文字幕 | 色91av| 国产精品第6页 | 国产第一页在线观看 | 日日操av | 一区二区视 | 俺来也俺也啪www色 欧洲一区二区视频 | 欧美理论片在线观看 | eeuss国产一区二区三区黑人 | 久国产视频 | 久久久一区二区三区 | 97超碰在线播放 | 欧美日韩999 | 深爱激情五月婷婷 | 在线观看中文字幕2021 | 91免费观看入口 | 黄色成人在线免费观看 | 超碰影院在线 | 国产最新自拍视频 | 欧美日韩成人一区 | 欧美日本一区 | 奴性白洁会所调教 | 天天插天天射天天干 | 成人3d动漫在线观看 | 国产伦精品免费视频 | 日本三级中国三级99人妇网站 | 亚洲图片欧美日韩 | 国产精品久久久久久久久久东京 | 小镇姑娘1979版 | 草av| 欧美xxxx吸乳 | 中文字幕av网址 | 开心激情av | 国产精品久久久影院 | 色播网址 | 日韩精品欧美精品 | 中文字幕乱码亚洲精品一区 | 欧美乱做爰xxxⅹ久久久 | 超碰青娱乐 | 天天舔天天摸 | 窝窝午夜视频 | 古装做爰无遮挡三级聊斋艳谭 | 亚洲福利社 | 少妇人妻好深好紧精品无码 | 女警白嫩翘臀呻吟迎合 | 国产成年视频 | 黄色在线视频播放 | 久久六| 99热精品免费| 国产精品人人 | h片免费观看 | 天天操夜夜爱 |