主頁 >  其他 > 干貨|一文搞定 uiautomator2 自動化測驗工具使用

干貨|一文搞定 uiautomator2 自動化測驗工具使用

2020-09-16 15:29:47 其他

一、背景簡介

Google 官方提供了一個 Android 自動化測驗工具(Java 庫),基于 Accessibility 服務,功能很強,可以對第三方 App 進行測驗,獲取螢屏上任意一個 App 的任意一個控制元件屬性,并對其進行任意操作,但有兩個缺點:

  1. 測驗腳本只能使用 Java 語言;
  2. 測驗腳本要打包成 jar 或者 apk 包上傳到設備上才能運行;

實際作業中,我們希望測驗邏輯能夠用 Python 撰寫,能夠在電腦上運行的時候就控制手機,所以基于這個目的開發了 python-uiautomator2 自動化測驗開源工具,其封裝了谷歌自帶的 uiautomator2 測驗框架,可以運行在支持 Python 的任一系統上,目前版本為 V2.10.2,

GitHub 開源地址:

https://github.com/openatx/uiautomator2

二、作業原理

 

 

 

如圖所示,python-uiautomator2 主要分為兩個部分,python 客戶端,移動設備

  • python 端: 運行腳本,并向移動設備發送 HTTP 請求;
  • 移動設備:移動設備上運行了封裝了 uiautomator2 的 HTTP 服務,決議收到的請求,并轉化成 uiautomator2 的代碼;

整個程序:

  1. 在移動設備上安裝 atx-agent(守護行程),隨后 atx-agent 啟動 uiautomator2 服務(默認 7912 埠)進行監聽;
  2. 在 PC 上撰寫測驗腳本并執行(相當于發送 HTTP 請求到移動設備的 server 端);
  3. 移動設備通過 WIFI 或 USB 接收到 PC 上發來的 HTTP 請求,執行制定的操作;

三、安裝與啟動

3.1 安裝 uiautomator2

使用 pip 安裝

pip install -U uiautomator2

安裝完成后,使用如下 python 代碼查看環境是事配置成功

說明:后文中所有代碼都需要匯入 uiautomator2 庫,為了簡化我使用 u2 代替,d 代表 driver

import uiautomator2 as u2# 連接并啟動d = u2.connect() print(d.info)

能正確列印出設備的資訊則表示安裝成功

注意:需要安裝 adb 工具,并配置到系統環境變數,才能操作手機,

安裝有問題可以到 issue 串列查詢:

https://github.com/openatx/uiautomator2/wiki/Common-issues

3.2 安裝 weditor

weditor 是一款基于瀏覽器的 UI 查看器,用來幫助我們查看 UI 元素定位,

因為 uiautomator 是獨占資源,所以當 atx 運行的時候 uiautomatorviewer 是不能用的,為了減少 atx 頻繁的啟停,就需要用到此工具

使用 pip 安裝

pip install -U weditor

  查看安裝是否成功

weditor --help

  出現如下資訊表示安裝成功

 

運行 weditor

 

python -m weditor#或者直接在命令列運行weditor

  

四、元素定位

4.1 使用方法

d(定位方式 = 定位值)#例:element = d(text='Phone')#這里回傳的是一個串列,當沒找到元素時,不會報錯,只會回傳一個長度為 0 的串列#當找到多個元素時,會回傳多個元素的串列,需要加下標再定位element[0].click()#獲取元素個數print(element.count)

  

4.2 支持的定位方式

ui2 支持 android 中 UiSelector 類中的所有定位方式,詳細可以在這個網址查看 developer.android.com/reference/a…

整體內容如下 , 所有的屬性可以通過 weditor 查看到

名稱描述

texttext 是指定文本的元素textContainstext 中包含有指定文本的元素textMatchestext 符合指定正則的元素textStartsWithtext 以指定文本開頭的元素classNameclassName 是指定類名的元素classNameMatchesclassName 類名符合指定正則的元素descriptiondescription 是指定文本的元素descriptionContainsdescription 中包含有指定文本的元素descriptionMatchesdescription 符合指定正則的元素descriptionStartsWithdescription 以指定文本開頭的元素checkable可檢查的元素,引數為 True,Falsechecked已選中的元素,通常用于復選框,引數為 True,Falseclickable可點擊的元素,引數為 True,FalselongClickable可長按的元素,引數為 True,Falsescrollable可滾動的元素,引數為 True,Falseenabled已激活的元素,引數為 True,Falsefocusable可聚焦的元素,引數為 True,Falsefocused獲得了焦點的元素,引數為 True,Falseselected當前選中的元素,引數為 True,FalsepackageNamepackageName 為指定包名的元素packageNameMatchespackageName 為符合正則的元素resourceIdresourceId 為指定內容的元素resourceIdMatchesresourceId 為符合指定正則的元素

4.3 子元素和兄弟定位

子**元素定位**

child()

 

#查找類名為 android.widget.ListView 下的 Bluetooth 元素d(className="android.widget.ListView").child(text="Bluetooth")# 下面這兩種方式定位有點不準確,不建議使用d(className="android.widget.ListView")\.child_by_text("Bluetooth",allow_scroll_search=True)d(className="android.widget.ListView").child_by_description("Bluetooth")

  

兄弟元素定位

sibling()

#查找與 google 同一級別,類名為 android.widget.ImageView 的元素d(text="Google").sibling(className="android.widget.ImageView")

  

鏈式呼叫

d(className="android.widget.ListView", resourceId="android:id/list") \  .child_by_text("Wi?Fi", className="android.widget.LinearLayout") \  .child(className="android.widget.Switch") \  .click()

  

4.4 相對定位

相對定位支持在left, right, top, bottom, 即在某個元素的前后左右

 

d(A).left(B),# 選擇 A 左邊的 Bd(A).right(B),# 選擇 A 右邊的 Bd(A).up(B), #選擇 A 上邊的 Bd(A).down(B),# 選擇 A 下邊的 B#選擇 WIFI 右邊的開關按鈕d(text='Wi?Fi').right(resourceId='android:id/widget_frame')

  

4.5 元素常用 API

表格標注有 @property 裝飾的類屬性方法,均為下方示例方式

d(test="Settings").exists

  

方法

描述回傳值備注

exists()判斷元素是否存在True,Flase@propertyinfo()回傳元素的所有資訊字典@propertyget_text()回傳元素文本字串

set_text(text)設定元素文本None

clear_text()清空元素文本None

center()回傳元素的中心點位置(x,y)基于整個螢屏的點

exists 其它使用方法:

d.exists(text='Wi?Fi',timeout=5)

  info() 輸出資訊:

{  "bounds": {    "bottom": 407,    "left": 216,    "right": 323,    "top": 342  },  "childCount": 0,  "className": "android.widget.TextView",  "contentDescription": null,  "packageName": "com.android.settings",  "resourceName": "android:id/title",  "text": "Wi?Fi",  "visibleBounds": {    "bottom": 407,    "left": 216,    "right": 323,    "top": 342  },  "checkable": false,  "checked": false,  "clickable": false,  "enabled": true,  "focusable": false,  "focused": false,  "longClickable": false,  "scrollable": false,  "selected": false}

  

可以通過上方資訊分別獲取元素的所有屬性

4.6 XPATH 定位

因為 Java uiautoamtor 中默認是不支持 xpath,這是屬于 ui2 的擴展功能,速度會相比其它定位方式慢一些

在 xpath 定位中,ui2 中的 description 定位需要替換為 content-desc,resourceId 需要替換為 resource-id

使用方法

# 只會回傳一個元素,如果找不到元素,則會報 XPathElementNotFoundError 錯誤# 如果找到多個元素,默認會回傳第 0 個d.xpath('//*[@resource-id="com.android.launcher3:id/icon"]')# 如果回傳的元素有多個,需要使用 all() 方法回傳串列# 使用 all 方法,當未找到元素時,不會報錯,會回傳一個空串列d.xpath('//*[@resource-id="com.android.launcher3:id/icon"]').all()

  

五、設備互動

5.1 單擊

d(text='Settings').click()#單擊直到元素消失 , 超時時間 10,點擊間隔 1d(text='Settings').click_gone(maxretry=10, interval=1.0)

  

5.2 長按

d(text='Settings').long_click()

  

5.3 拖動

Android<4.3 時不能使用拖動

# 在 0.25S 內將 Setting 拖動至 Clock 上,拖動元素的中心位置# duration 默認為 0.5, 實際拖動的時間會比設定的要高d(text="Settings").drag_to(text="Clock", duration=0.25)# 拖動 settings 到螢屏的某個點上d(text="Settings").drag_to(877,733, duration=0.25)#兩個點之間的拖動 , 從點 1 拖動至點 2d.drag(x1,y1,x2,y2)

  

5.4 滑動

滑動有兩個,一個是在 driver 上操作,一個是在元素上操作

元素上操作

從元素的中心向元素邊緣滑動

# 在 Setings 上向上滑動,steps 默認為 10# 1 步約為 5 毫秒,因此 20 步約為 0.1 sd(text="Settings").swipe("up", steps=20) 

  

driver 上操作

即對整個螢屏操作

# 實作下滑操作x,y = d.window_size()x1 = x / 2y1 = y * 0.1y2 = y * 0.9d.swipe(x1,y1,x1,y2)

  driver 滑動的擴展方法,可以直接實作滑動,不需要再自己封裝定位點

# 支持前后左右的滑動# "left", "right", "up", "down"# 下滑操作d.swipe_ext("down")

  

5.5 雙指操作

android>4.3

對元素操作

d(text='Settings').gesture(start1,start2,end1,end2,)# 放大操作d(text='Settings').gesture((525,960),(613,1121),(135,622),(882,1540))

  封裝好的放大縮小操作

# 縮小d(text="Settings").pinch_in()# 放大d(text="Settings").pinch_out()

  

5.6 等待元素出現或者消失

# 等待元素出現d(text="Settings").wait(timeout=3.0)# 等待元素消失,回傳 True False,timout 默認為全域設定的等待時間d(text='Settings').wait_gone(timeout=20)

  

5.7 滾動界面

設定 scrollable 屬性為 True;

滾動型別:horiz 為水平,vert 為垂直;

滾動方向:

  • forward 向前
  • backward 向后
  • toBeginning 滾動至開始
  • toEnd 滾動至最后
  • to 滾動直接某個元素出現

所有方法均回傳 Bool 值;

# 垂直滾動到頁面頂部 / 橫向滾動到最左側d(scrollable=True).scroll.toBeginning()d(scrollable=True).scroll.horiz.toBeginning()# 垂直滾動到頁面最底部 / 橫向滾動到最右側d(scrollable=True).scroll.toEnd()d(scrollable=True).scroll.horiz.toEnd()# 垂直向后滾動到指定位置 / 橫向向右滾動到指定位置d(scrollable=True).scroll.to(description=" 指定位置 ")d(scrollable=True).scroll.horiz.to(description=" 指定位置 ")# 垂直向前滾動(橫向同理)d(scrollable=True).scroll.forward()# 垂直向前滾動到指定位置(橫向同理)d(scrollable=True).scroll.forward.to(description=" 指定位置 ")# 滾動直到 System 元素出現d(scrollable=True).scroll.to(text="System")

Take screenshot of widgetim = d(text="Settings").screenshot()im.save("settings.jpg")

  

5.8 輸入

5.8.1 輸入自定義文本

# 使用 adb 廣播的方式輸入d.send_keys('hello')# 清空輸入框d.clear_text()

  

5.8.2 輸入按鍵

兩種方法

# 發送回車d.press('enter')# 第二種d.keyevent('enter')

  目前 press 支持的按鍵如下

"""        press key via name or key code. Supported key name includes:            home, back, left, right, up, down, center, menu, search, enter,            delete(or del), recent(recent apps), volume_up, volume_down,            volume_mute, camera, power.        """

  

keyevent 是通過 “adb shell input keyevent” 方式輸入,支持按鍵更加豐富

更多詳細的按鍵資訊 developer.android.com/reference/a…

5.8.3 輸入法切換

# 切換成 ui2 的輸入法,這里會隱藏掉系統原本的輸入法 , 默認是使用系統輸入法# 當傳入 False 時會使用系統默認輸入法,默認為 Fasled.set_fastinput_ime(True)# 查看當前輸入法d.current_ime()#回傳值('com.github.uiautomator/.FastInputIME', True)

  

5.8.4 模擬輸入法功能

可以模擬的功能有 go ,search ,send ,next, done ,previous,

如果使用 press 輸入按鍵無效,可以嘗試使用此方法輸入

# 搜索功能d.send_action("search")

  

5.9 toast 操作

# 獲取 toast, 當沒有找到 toast 訊息時,回傳 default 內容d.toast.get_message(timout=5,default='no toast')# 清空 toast 快取d.toast.reset()

  

5.10 監控界面

使用 wather 進行界面的監控,可以用來實作跳過測驗程序中的彈框

當啟動 wather 時,會新建一個執行緒進行監控

可以添加多個 watcher

用法

# 注冊監控 , 當界面內出現有 allow 字樣時,點擊 allowd.watcher.when('allow').click()# 移除 allow 的監控d.watcher.remove("allow")# 移除所有的監控d.watcher.remove()# 開始后臺監控d.watcher.start()d.watcher.start(2.0) # 默認監控間隔 2.0s# 強制運行所有監控d.watcher.run()# 停止監控d.watcher.stop()# 停止并移除所有的監控,常用于初始化d.watcher.reset()

  2.11.0 版本新增了一個 watch_context 方法 , 寫法相比 watcher 更簡潔,官方推薦使用此方法來實作監控,目前只支持 click() 這一種方法,

wct = d.watch_context()# 監控 ALLOWwct.when("ALLOW").click()# 監控 OKwct.when('OK').click() # 開啟彈窗監控,并等待界面穩定(兩個彈窗檢查周期內沒有彈窗代表穩定)wct.wait_stable()#其它實作代碼# 停止監控wct.stop()

  

5.11 多點滑動

這里可以用來實作圖案解鎖

使用 touch 類

# 模擬按下不放手touch.down(x,y)# 停住 3Stouch.sleep(x,y)# 模擬移動touch.move(x,y)# 模擬放開touch.up(x,y)#實作長按 , 同一個點按下休眠 5S 后抬起d.touch.down(252,1151).sleep(5).up(252,1151)# 實作四點的圖案解鎖,目前只支持坐標點d.touch.down(252,1151).move(559,1431).move(804,1674).move(558,1666).up(558,1666)

  

六、影像操作

6.1 截圖

d.screenshot('test.png')

  

6.2 錄制視頻

這個感覺是比較有用的一個功能,可以在測驗用例開始時錄制,結束時停止錄制,然后如果測驗 fail,則上傳到測驗報告,完美復原操作現場,具體原理后面再去研究,

首先需要下載依賴,官方推薦使用鏡像下載:

pip3 install -U "uiautomator2[image]" -i https://pypi.doubanio.com/simple

  執行錄制:

# 啟動錄制,默認幀率為 20d.screenrecord('test.mp4')# 其它操作time.sleep(10)#停止錄制,只有停止錄制了才能看到視頻 d.screenrecord.stop()

  

6.3 圖片識別點擊

下載與錄制視頻同一套依賴,

這個功能是首先手動截取需要點擊目標的圖片,然后 ui2 在界面中去匹配這個圖片,目前我嘗試了精確試不是很高,誤點率非常高,不建議使用,

# 點擊 d.image.click('test.png')# 匹配圖片,回傳相似度和坐標# {'similarity': 0.9314796328544617, 'point': [99, 630]}d.image.match('test.png')

  

七、應用管理

7.1 獲取當前界面的 APP 資訊

d.app_current()#回傳當前界面的包名,activity 及 pid{    "package": "com.xueqiu.android",    "activity": ".common.MainActivity",    "pid": 23007}

  

7.2 安裝應用

可以從本地路徑及 url 下載安裝 APP,此方法無回傳值,當安裝失敗時,會拋出 RuntimeError 例外

# 本地路徑安裝 d.app_install('test.apk')# url 安裝 d.app_install('http://s.toutiao.com/UsMYE/')

  

7.3 運行應用

默認當應用在運行狀態執行 start 時不會關閉應用,而是繼續保持當前界面,

如果需要消除前面的啟動狀態,則需要加 stop=True 引數,

# 通過包名啟動d.app_start("com.xueqiu.android",stop=True)#原始碼說明    def app_start(self, package_name: str,                   activity: Optional[str]=None,                   wait: bool = False,                   stop: bool=False,                   use_monkey: bool=False):        """ Launch application        Args:            package_name (str): package name            activity (str): app activity            stop (bool): Stop app before starting the activity. (require activity)            use_monkey (bool): use monkey command to start app when activity is not given            wait (bool): wait until app started. default False        """

  

7.4 停止應用

stop 和 clear 的區別是結束應用使用的命令不同

stop 使用的是 “am force-stop”

clear 使用的是 “pm clear”

# 通過包名結束單個應用d.app_stop("com.xueqiu.android")d.app_clear('com.xueqiu.android')# 結束所有應用 , 除了 excludes 引數串列中的應用包名# 如果不傳參,則會只保留兩個依賴服務應用# 會回傳一個結束應用的包名串列d.app_stop_all(excludes=['com.xueqiu.android'])

 

7.5 獲取應用資訊

 

d.app_info('com.xueqiu.android')#輸出{    "packageName": "com.xueqiu.android",    "mainActivity": "com.xueqiu.android.common.splash.SplashActivity",    "label": " 雪球 ",    "versionName": "12.6.1",    "versionCode": 257,    "size": 72597243}

  

7.6 獲取應用圖示

img = d.app_icon('com.xueqiu.android')img.save('icon.png')

  

7.7 等待應用啟動

# 等待此應用變為當前應用,回傳 pid,超時未啟動成功則回傳 0# front 為 true 表示等待 app 成為當前 app,# 默認為 false,表示只要后臺有這個應用的行程就會回傳 PIDd.app_wait('com.xueqiu.android',60,front=True)

  

7.8 卸載應用

# 卸載成功回傳 true, 沒有此包或者卸載失敗回傳 Falsed.app_uninstall('com.xueqiu.android')# 卸載所有自己安裝的第三方應用 , 回傳卸載 app 的包名串列# excludes 表示不卸載的串列# verbose 為 true 則會列印卸載資訊d.app_uninstall_all(excludes=[],verbose=True)

  卸載全部應用回傳的包名串列并一定是卸載成功了,最好使用 verbose=true 列印一下資訊,這樣可以查看到是否卸載成功

uninstalling com.xueqiu.android  OKuninstalling com.android.cts.verifier  FAIL

  或者可以修改一下原始碼,使其只輸出成功的包名,注釋的為增加的代碼,未注釋的是原始碼

def app_uninstall_all(self, excludes=[], verbose=False):        """ Uninstall all apps """        our_apps = ['com.github.uiautomator', 'com.github.uiautomator.test']        output, _ = self.shell(['pm', 'list', 'packages', '-3'])        pkgs = re.findall(r'package:([^\s]+)', output)        pkgs = set(pkgs).difference(our_apps + excludes)        pkgs = list(pkgs)        # 增加一個卸載成功的串列        #sucess_list = []        for pkg_name in pkgs:            if verbose:                print("uninstalling", pkg_name, " ", end="", flush=True)            ok = self.app_uninstall(pkg_name)            if verbose:                print("OK" if ok else "FAIL")                # 增加如下陳述句,當成功則將包名加入 list                #if ok:                 #   sucess_list.append(pkg_name)     # 回傳成功的串列    #    return sucess_list        return pkgs

  

八、其它實用方法

8.1 連接設備

#當 PC 只連接了一個設備時,可以使用此種方式d = u2.connect()#回傳的是 Device 類 , 此類繼承方式如下class Device(_Device, _AppMixIn, _PluginMixIn, _InputMethodMixIn, _DeprecatedMixIn):    """ Device object """# for compatible with old codeSession = Device

  connect() 可以使用如下其它方式進行連接

#當 PC 與設備在同一網段時,可以使用 IP 地址和埠號通過 WIFI 連接,無需連接 USB 線connect("10.0.0.1:7912")connect("10.0.0.1") # use default 7912 portconnect("http://10.0.0.1")connect("http://10.0.0.1:7912")#多個設備時,使用設備號指定哪一個設備connect("cff1123ea")  # adb device serial number

  

8.2 獲取設備及 driver 資訊

8.2.1 獲取 driver 資訊

d.info#輸出{    "currentPackageName": "com.android.systemui",    "displayHeight": 2097,    "displayRotation": 0,    "displaySizeDpX": 360,    "displaySizeDpY": 780,    "displayWidth": 1080,    "productName": "freedom_turbo_XL",    "screenOn": true,    "sdkInt": 29,    "naturalOrientation": true}

  

8.2.2 獲取設備資訊

會輸出測驗設備的所有資訊,包括電池,CPU,記憶體等

d.device_info#輸出{    "udid": "61c90e6a-ba:1b:ba:46:91:0e-freedom_turbo_XL",    "version": "10",    "serial": "61c90e6a",    "brand": "Schok",    "model": "freedom turbo XL",    "hwaddr": "ba:1b:ba:46:91:0e",    "port": 7912,    "sdk": 29,    "agentVersion": "0.9.4",    "display": {        "width": 1080,        "height": 2340    },    "battery": {        "acPowered": false,        "usbPowered": true,        "wirelessPowered": false,        "status": 2,        "health": 2,        "present": true,        "level": 98,        "scale": 100,        "voltage": 4400,        "temperature": 292,        "technology": "Li-ion"    },    "memory": {        "total": 5795832,        "around": "6 GB"    },    "cpu": {        "cores": 8,        "hardware": "Qualcomm Technologies, Inc SDM665"    },    "arch": "",    "owner": null,    "presenceChangedAt": "0001-01-01T00:00:00Z",    "usingBeganAt": "0001-01-01T00:00:00Z",    "product": null,    "provider": null}

  

8.2.3 獲取螢屏解析度

# 回傳(寬,高)元組d.window_size()# 例 解析度為 1080*1920# 手機豎屏狀態回傳 (1080,1920)# 橫屏狀態回傳 (1920,1080)

  

8.2.4 獲取 IP 地址

# 回傳(寬,高)元組d.window_size()# 例 解析度為 1080*1920# 手機豎屏狀態回傳 (1080,1920)# 橫屏狀態回傳 (1920,1080)

  

8.2.4 獲取 IP 地址

# 回傳 ip 地址字串,如果沒有則回傳 Noned.wlan_ip

  

8.3 driver 全域設定

8.3.1 使用 settings 設定

查看 settings 默認設定

d.settings#輸出{    #點擊后的延遲,(0,3)表示元素點擊前等待 0 秒,點擊后等待 3S 再執行后續操作    'operation_delay': (0, 3),    # opretion_delay 生效的方法,默認為 click 和 swipe    # 可以增加 press,send_keys,long_click 等方式    'operation_delay_methods': ['click', 'swipe'],    # 默認等待時間,相當于 appium 的隱式等待    'wait_timeout': 20.0,    # xpath 日志    'xpath_debug': False}

  修改默認設定,只需要修改 settings 字典即可

#修改延遲為操作前延遲 2S 操作后延遲 4.5Sd.settings['operation_delay'] = (2,4.5)#修改延遲生效方法d.settings['operation_delay_methods'] = {'click','press','send_keys'}# 修改默認等待d.settings['wait_timeout'] = 10

  

8.3.2 使用方法或者屬性設定

  • http 默認請求超時時間

    默認值 60s, d.HTTP_TIMEOUT = 60

  • 當設備掉線時,等待設備在線時長

    僅當 TMQ=true 時有效,支持通過環境變數 WAIT_FOR_DEVICE_TIMEOUT 設定d.WAIT_FOR_DEVICE_TIMEOUT = 70

  • 元素查找默認等待時間

    打不到元素時,等待 10 后再報例外d.implicitly_wait(10.0)

  • 打開 HTTP debug 資訊

    d.debug = Trued.info#輸出15:52:04.736 $ curl -X POST -d '{"jsonrpc": "2.0", "id": "0eed6e063989e5844feba578399e6ff8", "method": "deviceInfo", "params": {}}' 'http://localhost:51046/jsonrpc/0'15:52:04.816 Response (79 ms) >>>{"jsonrpc":"2.0","id":"0eed6e063989e5844feba578399e6ff8","result":{"currentPackageName":"com.android.systemui","displayHeight":2097,"displayRotation":0,"displaySizeDpX":360,"displaySizeDpY":780,"displayWidth":1080,"productName":"freedom_turbo_XL","screenOn":true,"sdkInt":29,"naturalOrientation":true}}<<< END

  • 休眠

    相當于 time.sleep(10)d.sleep(10)

8.4 亮滅屏

# 亮屏d.screen_on()# 滅屏d.screen_off()

  

8.5 螢屏方向

# 設定螢屏方向d.set_orientation(value)# 獲取當前螢屏方向d.orientation

  value 值參考,只要是元組中的任一一個值就可以,

# 正常豎屏(0, "natural", "n", 0), # 往左橫屏,相當于手機螢屏順時針旋轉 90 度# 現實中如果要達到此效果,需要將手機逆時針旋轉 90 度 (1, "left", "l", 90),# 倒置,這個需要看手機系統是否支持 , 倒過來顯示  (2, "upsidedown", "u", 180), # 往右橫屏,調整與往左相反,螢屏順時針旋轉 270 度 (3, "right", "r", 270))

  

8.6 打開通知欄與快速設定

打開通知欄

d.open_notification()

  打開快速設定

d.open_quick_settings()

  

8.7 檔案匯入匯出

8.7.1 匯入檔案

# 如果是目錄,這里 "/sdcrad/" 最后一個斜杠一定要加,否則會報錯d.push("test.txt","/sdcrad/")d.push("test.txt","/sdcrad/test.txt")

  

8.7.2 匯出檔案

d.pull('/sdcard/test.txt','text.txt')

  

8.8 執行 shell 命令

使用 shell 方法執行

8.8.1 執行非阻塞命令

output 回傳的是一個整體的字串,如果需要抽取值,需要對 output 進行決議提取處理

# 回傳輸出和退出碼,正常為 0,例外為 1output,exit_code = d.shell(["ls","-l"],timeout=60)

  

8.8.2 執行阻塞命令(持續執行的命令)

# 回傳一個命令的資料流 output 為 requests.models.Responseoutput = d.shell('logcat',stream=True)try:    # 按行讀取,iter_lines 為迭代回應資料,一次一行    for line in output.iter_lines():        print(line.decode('utf8'))finally:    output.close()

  原始碼描述

def shell(self, cmdargs: Union[str, List[str]], stream=False, timeout=60):        """        Run adb shell command with arguments and return its output. Require atx-agent >=0.3.3        Args:            cmdargs: str or list, example: "ls -l" or ["ls", "-l"]            timeout: seconds of command run, works on when stream is False            stream: bool used for long running process.        Returns:            (output, exit_code) when stream is False            requests.Response when stream is True, you have to close it after using        Raises:            RuntimeError        For atx-agent is not support return exit code now.        When command got something wrong, exit_code is always 1, otherwise exit_code is always 0        """

  

8.9 session(目前已經被棄用)

8.10 停止 UI2 服務

因為有 atx-agent 的存在,Uiautomator 會被一直守護著,如果退出了就會被重新啟動起來,但是 Uiautomator 又是霸道的,一旦它在運行,手機上的輔助功能、電腦上的 uiautomatorviewer 就都不能用了,除非關掉該框架本身的 uiautomator

使用代碼停止

d.service("uiautomator").stop()

  

手動停止

直接打開 ATX APP(init 成功后,就會安裝上),點擊關閉 UIAutomator

以上,歡迎大家一起交流探討,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/58123.html

標籤:其他

上一篇:講解如何使用apipost進行介面自動化測驗

下一篇:idea 代碼顏色修改

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more