python +uiautomator2 app測試環境搭建,摒棄appium復雜的環境依賴


1.前言關於uiautomator2:

python-uiautomator2封裝了谷歌自帶的uiautomator2測試框架,提供便利的python接口。他允許測試人員直接在PC上編寫Python的測試代碼,操作手機應用,完成自動化,大大提高了自動化代碼編寫的效率。

工作原理

以下圖片使用Windows畫圖軟件

 

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

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

版本要求:

本案例以genymotion模擬器為例sdk api version 5.0 :

Requirements uiautomator2

  • Android版本 4.4+
  • Python 3.6+ (社區反饋3.8.0不支持, 但是3.8.2支持)

如果用python2的pip安裝,會安裝本庫的老版本0.2.3;如果用python3.5的pip安裝,會安裝本庫的老版本0.3.3;兩者均已經不會再維護;PYPI上的最近版本是這個:https://pypi.org/project/uiautomator2/

一.環境搭建:

adb connect  ip:port genymotion 默認端口5555,ip為安卓機器ip)這里我以wifi連接為案例:實際usb,wifi,自己決定

python -m uiautomator2 init

 

 

QUICK START

先准備一台(不要兩台)開啟了開發者選項的安卓手機,連接上電腦,確保執行adb devices可以看到連接上的設備。

運行pip3 install -U uiautomator2 安裝uiautomator2

運行python3 -m uiautomator2 init安裝包含httprpc服務的apk到手機+atx-agent, minicap, minitouch (在過去的版本中,這一步是必須執行的,但是從1.3.0之后的版本,當運行python代碼u2.connect()時就會自動推送這些文件了)

命令行運行python打開python交互窗口。然后將下面的命令輸入到窗口中。

import uiautomator2 as u2 d = u2.connect() # connect to device print(d.info)

這時看到類似下面的輸出,就可以正式開始用我們這個庫了。因為這個庫功能太多,后面還有很多的內容,需要慢慢去看 ....

{'currentPackageName': 'net.oneplus.launcher', 'displayHeight': 1920, 'displayRotation': 0, 'displaySizeDpX': 411, 'displaySizeDpY': 731, 'displayWidth': 1080, 'productName': 'OnePlus5', '
screenOn': True, 'sdkInt': 27, 'naturalOrientation': True}

二.示范代碼:
import uiautomator2 as u2
"""
https://github.com/openatx/atx-agent/releases
https://github.com/openatx/android-uiautomator-server/releases
https://github.com/openatx/uiautomator2/wiki/Manual-Init
adb shell rm /data/local/tmp/minicap
adb shell rm /data/local/tmp/minicap.so
adb shell rm /data/local/tmp/minitouch
adb shell /data/local/tmp/atx-agent server --stop
adb shell rm /data/local/tmp/atx-agent
adb uninstall com.github.uiautomator
adb uninstall com.github.uiautomator.test
"""
dev=u2.connect("192.168.172.102")
print(dev.info)

調試工具:weditor:

what is weditor ?:用來抓取手機上應用的控件,坐標以及元素屬性id,text,description etc;

雖然很想用Android SDK內置工具uiautomatorviewer.bat,但是運行uiautomator2的時候,uiautomatorviewer.bat運行不起來,兩者之間沖突太嚴重。
於是參考着uiautomatorviewer的界面,我又寫了一個weditor,調用python-uiautomator2的兩個接口screenshotdump_hierarchy這樣就不會有沖突問題了

Install weditor (UI Inspector)

因為uiautomator是獨占資源,所以當atx運行的時候uiautomatorviewer是不能用的,為了減少atx頻繁的啟停,我們開發了基於瀏覽器技術的weditor UI查看器。https://github.com/openatx/weditor

安裝方法(備注: 目前最新的穩定版為 0.1.0)

pip install -U weditor

安裝好之后,就可以在命令行運行weditor --help 確認是否安裝成功了。

Windows系統可以使用命令在桌面創建一個快捷方式 weditor --shortcut

命令行直接輸入python -m  weditor 會自動打開瀏覽器,輸入設備的ip或者序列號,點擊Connect即可。

 

 

定位方式

  1. ResourceId定位: d(resourceId="com.smartisanos.clock:id/text_stopwatch").click()
  2. Text定位 d(text="秒表").click()
  3. Description定位 d(description="..").click()
  4. ClassName定位 d(className="android.widget.TextView").click()

xpath定位並不支持,一開始打算做支持的,但是發現不用也能搞定。就是代碼寫的長一點而已。

操作控件

# click
d(text="Settings").click()

# long click
d(text="Settings").long_click()

# 等待元素的出現
d(text="Settings").wait(timeout=10.0)

九宮格解鎖:以前文章寫過 https://testerhome.com/topics/11034

中文字符的輸入
如果可以定位到元素,直接通過set_text就可以輸入中文

d(text="Settings").set_text("你好")

如果定位不到元素需要使用send_keys方法,以及切換輸入法

d.set_fastinput_ime(True)
d.send_keys("你好 Hello")
d.set_fastinput_ime(False) # 輸入法用完關掉

截圖:d.screenshot("home.jpg")
獲取圖層信息:xml = d.dump_hierarchy()

 

Connect to a device

There are two ways to connect to the device.

  1. Through WiFi

Suppose device IP is 10.0.0.1 and your PC is in the same network.

import uiautomator2 as u2 d = u2.connect('10.0.0.1') # alias for u2.connect_wifi('10.0.0.1') print(d.info)
  1. Through USB

Suppose the device serial is 123456f (seen from adb devices)

import uiautomator2 as u2 d = u2.connect('123456f') # alias for u2.connect_usb('123456f') print(d.info)
  1. Through ADB WiFi
import uiautomator2 as u2 d = u2.connect_adb_wifi("10.0.0.1:5555") # Equals to # + Shell: adb connect 10.0.0.1:5555 # + Python: u2.connect_usb("10.0.0.1:5555")

Calling u2.connect() with no argument, uiautomator2 will obtain device IP from the environment variable ANDROID_DEVICE_IP or ANDROID_SERIAL. If this environment variable is empty, uiautomator will fall back to connect_usb and you need to make sure that there is only one device connected to the computer.

 

Command line

其中的$device_ip代表設備的ip地址

如需指定設備需要傳入--serial 如 python3 -m uiautomator2 --serial bff1234 <SubCommand>, SubCommand為子命令(init,或者screenshot等)

1.0.3 Added: python3 -m uiautomator2可以簡寫為uiautomator2

  • screenshot: 截圖

    $ uiautomator2 screenshot screenshot.jpg
  • current: 獲取當前包名和activity

    $ uiautomator2 current
    {
        "package": "com.android.browser", "activity": "com.uc.browser.InnerUCMobile", "pid": 28478 }
  • uninstall: 卸載

    $ uiautomator2 uninstall <package-name> # 卸載一個包 $ uiautomator2 uninstall <package-name-1> <package-name-2> # 卸載多個包 $ uiautomator2 uninstall --all # 全部卸載
  • stop: 停止應用

    $ uiautomator2 stop com.example.app # 停止一個app $ uiautomator2 stop --all # 停止所有的app
  • install: 安裝apk,apk通過URL給出 (暫時不能用)

  • healthcheck: 健康檢查 (暫不能用)

還有太多太多的操作,我就不寫了。更多更詳細的API接口文檔,直接去Github上看文檔吧, 記得留下你的Starhttps://github.com/openatx/uiautomator2

有問題可以來我的技術群咨詢,本文系作者原創,禁止抄襲以及商業化使用,如有轉載聲明作者出處,尊重技術探索:

 

文章最后送上一個網易雲音樂的demo:

# coding=utf-8
import uiautomator2 as u2
import time

d = u2.connect('emulator-5554')
d.wait_timeout=20 # setting wait implicit_wait time
print(d.info)
d.app_clear("com.netease.cloudmusic")
d(text="網易雲音樂").click()  # d.app_start/stop("com.netease.cloudmusic")
d(resourceId="com.netease.cloudmusic:id/agree").click()
time.sleep(8)
d(resourceId="com.netease.cloudmusic:id/agreeCheckbox").click()
d(resourceId="com.netease.cloudmusic:id/login").click()
d.send_keys("18676741234", clear=True)
d(resourceId="com.netease.cloudmusic:id/next").click()
time.sleep(3)
d.send_keys("yourpassword", clear=True)
d(resourceId="com.netease.cloudmusic:id/login").click()
time.sleep(5)
d(description="搜索").click()
d(resourceId="com.netease.cloudmusic:id/search_src_text").click()
d.send_keys("虛擬", clear=True)
d(text="虛擬青鋼影").click()
d(resourceId="com.netease.cloudmusic:id/songName", text='Camille,the Steel Shadow ("青鋼影 卡蜜爾"主題曲)').click()
d(resourceId="com.netease.cloudmusic:id/playBtn").click()
d(description="轉到上一層級").click()
d(resourceId="com.netease.cloudmusic:id/search_src_text").click()
d.send_keys("虛擬", clear=True)
d(resourceId="com.netease.cloudmusic:id/songInfoContainer").click()
d(resourceId="com.netease.cloudmusic:id/songName", text="丟了你(抖音版)(翻自 井朧)").click()
time.sleep(20)
d.app_clear("com.netease.cloudmusic")

  

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM